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

时间:2016-08-17 19:24:58

标签: powershell

我需要修改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

2 个答案:

答案 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