使用管道更改CSV文件中的一个字段失败

问题描述:

我需要修改CSV文件中的一个(1)字段。我可以用单独的命令来完成,但CSV文件可能很大(GiB +)。我的理解是Import-Csv会将整个文件读入内存,除非它被传送到另一个进程。那是对的吗?使用管道更改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 

你的管道版本混合起来并且没有输出(修改,但不写任何东西到输出管道)。

Import-Csv $infile | 
    ForEach-Object { 
     # This sets the value 
     $_.Name = $_.Name + '-bedoo' 
     # This is output (post-modification) 
     $_ 
    } | 
    Export-Csv ".\eximtest-b.csv" -NoTypeInformation 
+0

谢谢。这工作。 – lit

$行未在您的管道方法中定义。将$ 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 
+0

是的,你是对的。 – lit