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-File
,Set-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}
方法为字符串。
我无法理解为什么我的 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-File
,Set-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.
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}
方法为字符串。