csv 如何从文本文件导入PSObject数组?

ncgqoxb0  于 2023-02-01  发布在  其他
关注(0)|答案(3)|浏览(158)

这就足够了:

PS C:\Users\saunders\Desktop\data>
PS C:\Users\saunders\Desktop\data> ls .\test.csv

    Directory: C:\Users\saunders\Desktop\data

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2023-01-31   1:38 PM            640 test.csv

PS C:\Users\saunders\Desktop\data>
PS C:\Users\saunders\Desktop\data> cat .\test.csv
UserPrincipalName,"DisplayName","Title","UserType","IsLicensed"
LeeG@lazydev.com,"Lee Gu","jr engineer","Member","True"
MeganB@lazydev.com,"Megan Bowen","recruiter","Member","True"
GradyA@lazydev.com,"Grady Archie","sr engineer","Member","True"
MiriamG@lazydev.com,"Miriam Graham","Director","Member","True"
openmailbox@lazydev.com,"openmailbox",,"Member","False"
JohannaL@lazydev.com,"Johanna Lorenz","Senior Engineer","Member","True"
JoniS@lazydev.com,"Joni Sherman","recruiter","Member","False"
AlexW@lazydev.com,"Alex Wilber","Marketing Assistant","Member","True"
IsaiahL@lazydev.com,"Isaiah Langer","Sales Rep","Member","True"
PS C:\Users\saunders\Desktop\data>
PS C:\Users\saunders\Desktop\data> $test = Import-CSV .\test.csv
PS C:\Users\saunders\Desktop\data>
PS C:\Users\saunders\Desktop\data> $test[3]

UserPrincipalName : MiriamG@lazydev.com
DisplayName       : Miriam Graham
Title             : Director
UserType          : Member
IsLicensed        : True


PS C:\Users\saunders\Desktop\data>

但是如何从格式化的文本文件中获取CSV格式的数据呢?

PS C:\Users\saunders\Desktop\data>
PS C:\Users\saunders\Desktop\data> $records = Get-Content .\records.txt
PS C:\Users\saunders\Desktop\data>
PS C:\Users\saunders\Desktop\data> $records

UserPrincipalName : LeeG@lazydev.com
DisplayName       : Lee Gu
Title             : jr engineer
UserType          : Member
IsLicensed        : True

UserPrincipalName : MeganB@lazydev.com
DisplayName       : Megan Bowen
Title             : recruiter
UserType          : Member
IsLicensed        : True

UserPrincipalName : GradyA@lazydev.com
DisplayName       : Grady Archie
Title             : sr engineer
UserType          : Member
IsLicensed        : True

UserPrincipalName : MiriamG@lazydev.com
DisplayName       : Miriam Graham
Title             : Director
UserType          : Member
IsLicensed        : True

UserPrincipalName : openmailbox@lazydev.com
DisplayName       : openmailbox
Title             :
UserType          : Member
IsLicensed        : False

UserPrincipalName : JohannaL@lazydev.com
DisplayName       : Johanna Lorenz
Title             : Senior Engineer
UserType          : Member
IsLicensed        : True

UserPrincipalName : JoniS@lazydev.com
DisplayName       : Joni Sherman
Title             : recruiter
UserType          : Member
IsLicensed        : False

UserPrincipalName : AlexW@lazydev.com
DisplayName       : Alex Wilber
Title             : Marketing Assistant
UserType          : Member
IsLicensed        : True

UserPrincipalName : IsaiahL@lazydev.com
DisplayName       : Isaiah Langer
Title             : Sales Rep
UserType          : Member
IsLicensed        : True

PS C:\Users\saunders\Desktop\data>

这样每条记录的数据都会被转置,然后写入CSV文件中的一行。毫无疑问,有一个term用于执行这种逆操作。它本身不必是CSV,只是上面的示例源自CSV。
请纠正任何术语错误。
就目前情况而言,$records对象本身不能直接导出回CSV:

PS C:\Users\saunders\Desktop\data>
PS C:\Users\saunders\Desktop\data> $records = Get-Content .\records.txt
PS C:\Users\saunders\Desktop\data>
PS C:\Users\saunders\Desktop\data> Export-Csv $records
Export-Csv : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Path'. Specified method is not supported.
At line:1 char:12
+ Export-Csv $records
+            ~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Export-Csv], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.ExportCsvCommand

PS C:\Users\saunders\Desktop\data>

因为首先必须以某种方式对其进行解析。

ztyzrc3y

ztyzrc3y1#

您显示的文本格式是 * for-display * 格式,由PowerShell的Format-List cmdlet生成。
因此,它不适用于 * 程序化 * 处理,因此没有标准的cmdlet可以解析这种格式。
对于 * 程序化 * 处理,应该使用 * 结构化 * 文本格式,如JSON或CSV,或者--为了获得最大的结构灵活性和最佳(尽管有限)类型保真度--PowerShell基于XML的CLIXML格式,由Export-Clixml生成,Import-Clixml可以理解。
如果您被给定的格式卡住了,那么您必须自己进行解析;例如:

# Outputs [pscustomobject] instances that can be exported to CSV, for instance.
((Get-Content -Raw records.txt) -replace ':', '=') -split '\r?\n\r?\n' | 
  ConvertFrom-StringData | 
  ForEach-Object { [pscustomobject] $_ }

以上是相对简单的,但是:

  • 假设所有属性 * values * 都不包含:(这可以解决),并且所有值都是 * 单行 *;这些值也服从于\字符的解释,作为换码序列的开始(参见下一个要点中的cmdlet链接)。
  • 有一个"不可避免"的缺点因为ConvertFrom-StringData固有地输出 * 无序 * hashtables,所以不保留属性顺序。
  • GitHub issue #19070的主题是在未来的PowerShell版本(7.3.2之后的版本,截至本文撰写时的最新版本)中修复此问题

如果维护属性顺序很重要,并且您知道属性名称,则可以通过管道将按所需顺序列出的属性名称作为-Property参数传递到Select-Object调用。
否则,您必须自己解析文本文件行。

hmmo2u0o

hmmo2u0o2#

虽然还没有完全实现,但是

wsl >
wsl > pwd
/mnt/c/WINDOWS/system32/awk
wsl >
wsl > awk '{print $1}' input.txt | datamash transpose
A       B       C       D
wsl >
wsl > awk '{print $2}' input.txt | datamash transpose
2014    2013    2014    2014
wsl >
wsl > awk '{print $3}' input.txt | datamash transpose
1002    990     2030    599
wsl >
wsl > cat input.txt
A        2014   1002
B        2013    990
C        2014   2030
D        2014    599
wsl >

其中每个记录一次转置矩阵一行。
上述输出在串联后将为:

A       B       C       D
2014    2013    2014    2014
1002    990     2030    599

至少乍一看,它可以很容易地导入为CSV。然而,它不是PowerShell解决方案。

wrrgggsh

wrrgggsh3#

特别是对于Windows PowerShell,您可以选择使用ConvertFrom-String 's template-based parsing功能:

# define a template using the data from 2 consecutive records from the input data
$recordTemplate = @'
UserPrincipalName : {UserPrincipalName*:LeeG@lazydev.com}
DisplayName       : {DisplayName:Lee Gu}
Title             : {Title:jr engineer}
UserType          : {UserType:Member}
IsLicensed        : {IsLicensed:True}

UserPrincipalName : {UserPrincipalName*:MeganB@lazydev.com}
'@

# ConvertFrom-String will use the example(s) in the template to infer the format of the remaining records
Get-Content .\records.txt | ConvertFrom-String -TemplateContent $recordTemplate

相关问题