我需要修改CSV文件中的一(1)个字段。我可以使用单独的命令来完成它,但CSV文件可能很大(GiB +)。我的理解是Import-Csv
会将整个文件读入内存,除非它被传送到另一个进程。这是对的吗?
在小文件上使用单独的命令可以正常工作,但是pipelined命令不会产生任何输出。我错过了什么?
PS C:\src\powershell> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
4 0 -1 -1
PS C:\src\powershell> Get-Content .\eximtest.ps1
$infile = ".\eximtest.csv"
"id,name,breed
1,Ruby,cat
2,Ralph,dog
3,Asia,cat" | Out-File $infile
# Non-pipeline approach, reads all of $infile into $csv
$csv = Import-Csv $infile
foreach($row in $csv) { $row.name = $row.name + "-bedoo" }
$csv | Export-Csv ".\eximtest-a.csv" -NoTypeInformation
# Pipeline approach, pipes $infile to next process as read
Import-Csv $infile | `
foreach($_) { $row.name = $row.name + "-bedoo" } | `
Export-Csv ".\eximtest-b.csv" -NoTypeInformation
运行脚本会生成正确的文件(永远不要引用引号)。但是pipelined命令会生成一个零(0)长度的文件。
PS C:\src\powershell> .\eximtest.ps1
PS C:\src\powershell> Get-ChildItem .\eximtest-*.csv
Directory: C:\src\powershell
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2016-08-17 14:12 94 eximtest-a.csv
-a--- 2016-08-17 14:12 0 eximtest-b.csv
非常感谢大家。工作版。
Import-Csv $infile | `
Foreach-Object {$_.name = $_.name + "-bedoo"; $_} | `
Export-Csv ".\eximtest-b.csv" -NoTypeInformation
答案 0 :(得分:1)
$ Row未在您的管道方法中定义。将$ row更改为$ _并将foreach($ _)循环更改为foreach,你应该很好。
# Pipeline approach, pipes $infile to next process as read
Import-Csv $infile | `
foreach { $_.name = $_.name + "-bedoo" } | `
Export-Csv ".\eximtest-b.csv" -NoTypeInformation
答案 1 :(得分:0)
您的管道版本已混淆且没有输出(您修改,但不向输出管道写入任何内容)。
Import-Csv $infile |
ForEach-Object {
# This sets the value
$_.Name = $_.Name + '-bedoo'
# This is output (post-modification)
$_
} |
Export-Csv ".\eximtest-b.csv" -NoTypeInformation