2016-08-17 19 views
0

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

回答

0

你的管道版本混合起來並且沒有輸出(修改,但不寫任何東西到輸出管道)。

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

1

$行未在您的管道方法中定義。將$ 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