Powershell export-csv return 数字

Powershell export-csv return numbers

我无法理解为什么我的 csv 只导出 return 数字而不是我想要的字符串。当我使用 out-file 而不是 export-csv 时,一切看起来都很好。

$get_child_csv = Get-ChildItem $c_path -ErrorVariable +errors | ?{ $_.PSIsContainer } | select fullname | foreach {$_.fullname} | Export-Csv ".\childitems\csv$item.csv" -NoTypeInformation -Encoding unicode
$get_child_txt = Get-ChildItem $c_path -ErrorVariable +errors_txt | ?{ $_.PSIsContainer } | select fullname | foreach { $_.fullname } | Out-File ".\childitems\txt$item.txt"

CSV 输出示例:

Length
41
41
41
41

TXT 输出:

\SERVER\FILESHARE\FOLDER
\SERVER\FILESHARE\FOLDER
\SERVER\FILESHARE\FOLDER
\SERVER\FILESHARE\FOLDER

我做错了什么?

Export-CSV 用于导出具有多个属性的 object。输出的格式是每行一个 object,第一行是 header,描述以下行的 columns/properties,例如:

Property1,Property2
11,12
21,22

由于以下代码 foreach { $_.FullName } | Export-CSV ...,您正在尝试为 FullName-属性 导出 string-value。一个字符串 object 只有一个 属性 也就是 "Length" 如下所示,这就是为什么你的 CSV 只包含长度 header 和每个路径的长度的原因(每行一个):

PS > Get-ChildItem | foreach {$_.fullname} | Get-Member -MemberType Properties   

   TypeName: System.String

Name   MemberType Definition       
----   ---------- ----------       
Length Property   int Length {get;}

如果你只想保存路径(单个property/value),那么你不应该使用Export-CSV,而是Out-FileSet-Content来创建一个普通的文本文件:

Get-ChildItem $c_path | ?{ $_.PSIsContainer } | foreach { $_.fullname } | Out-File ".\childitems\txt$item.txt"

如果您想使用有效的 CSV(需要 header),那么您可以删除 foreach {$_.fullname} | 以获得此输出:

PS > Get-ChildItem $c_path -ErrorVariable +errors | ?{ $_.PSIsContainer } | select fullname | Export-Csv ".\childitems\csv$item.csv" -NoTypeInformation -Encoding unicode

FullName
Path1
Path2

旁注:您可以将 object 转换为 CSV,跳过第一行 (header),然后使用 Out-File 等保存。就像下面的示例一样,得到 header-less csv-file,但确实没有理由对每个 object.

的单个 property/column/value 使用 CSV
PS > gci | select fullname | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1
"C:\Users\frodeD Objects"
"C:\Users\frode\Contacts"
"C:\Users\frode\Desktop"

回答

Frode F. 解释了为什么它没有按预期工作是正确的,但是有一种简单的方法可以获取字符串数组并将它们从管道中放入 CSV 中:

'first','second','third' |
     ForEach-Object {New-Object psobject -Property @{'String' = $_}} |
     Export-Csv ".\string_example.csv" -NoTypeInformation

如果您希望此部分在管道中作为 one-liner 重用:

%{New-Object psobject -Prop @{$propName=$_}}

(只需要提前定义$propName或者用字符串替换$propName即可)

解释

通过使用 ForEach{New-Object},我们获取数组中的每个字符串,并显式创建一个 object 并命名为 属性,其值是管道中的字符串。

重温 Frode F. 所说的,Export-Csv 将从传递的 object 中获取属性。如果你想比较原始方式的 属性 成员与 ForEach{New-Object},请尝试以下代码:

$stringArray = 'first','second','third'

# Original
$stringArray |
     Get-Member -MemberType Properties

# With ForEach{New-Object}
$stringArray |
     ForEach-Object {New-Object psobject -prop @{'String' = $_}} |
     Get-Member -MemberType Properties

结果如下:

   TypeName: System.String

Name   MemberType Definition       
----   ---------- ----------       
Length Property   int Length {get;}


   TypeName: System.Management.Automation.PSCustomObject

Name     MemberType   Definition                        
----     ----------   ----------                        
String   NoteProperty System.String String=first

"Name" 字段中的条目将被 Export-Csv 用作 headers,而 "Definition" 部分将用作内容。请注意,"Definition" 字段列出了将要传递的数据类型——原始类型为 int,ForEach{New-Object} 方法为字符串。