我费了好大的劲才弄明白为什么这个脚本没有按预期工作。这是一个简单的脚本,我在其中尝试导入 CSV,选择我想要的几列,然后导出 CSV 并复制自身。 (基本上我们已经归档了数据,由于内存大小限制,我只需要从另一个项目中提取几列)。这个脚本非常简单,它显然与它不起作用时造成的挫败感成反比关系……现在的最终结果是我得到一个空的 csv 而不是只包含我选择的列的 csv使用选择对象。
$RootPath = "D:\SomeFolder"
$csvFilePaths = Get-ChildItem $RootPath -Recurse -Include *.csv |
ForEach-Object{
Import-CSV $_ |
Select-Object Test_Name, Test_DataName, Device_Model, Device_FW, Data_Avg_ms, Data_StdDev |
Export-Csv $_.FullName -NoType -Force
}
最佳答案
除非您预先完整地将输入文件读入内存,否则您无法在给定管道中安全地读取和写回同一文件。
具体来说,Import-Csv file.csv | 这样的命令... | Export-Csv file.csv
将删除 file.csv
的内容。
最简单的解决方案是将读取输入文件的命令包含在(...)
中,但请注意:
文件的内容(转换为对象)必须作为一个整体放入内存。
如果管道在所有(已转换的)对象都被写回文件之前中断,则存在数据丢失的轻微风险。
应用于您的命令:
$RootPath = "D:\SomeFolder"
Get-ChildItem $RootPath -Recurse -Include *.csv -OutVariable csvFiles |
ForEach-Object{
(Import-CSV $_.FullName) | # NOTE THE (...)
Select-Object Test_Name, Test_DataName, Device_Model, Device_FW,
Data_Avg_ms, Data_StdDev |
Export-Csv $_.FullName -NoType -Force
}
请注意,我使用了 -OutVariable csvFiles
来收集输出变量 $csvFiles
中的 CSV 文件信息对象。您通过 $csvFilePaths = ...
收集文件路径的尝试不起作用,因为它试图收集 Export-Csv
的输出,但 Export-Csv
不产生任何输出。
此外,为了安全起见,我已将 Import-Csv
参数从 $_
更改为 $_.FullName
以确保Import-Csv
找到输入文件(因为遗憾的是,文件信息对象 $_
被绑定(bind)为一个字符串,有时 扩展为纯文件名)。
更安全的解决方案是首先输出到一个临时文件,并且(仅)在成功完成后替换原始文件。
无论采用哪种方法,替换文件都将具有默认文件属性和权限;如果原始文件具有您想要保留的特殊属性和/或权限,则必须明确地重新创建它们。
关于powershell - PS 脚本正在导出空 CSV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51272251/