PS 脚本正在导出空 CSV
PS Script is exporting an empty CSVs
我费了好大的劲才弄明白为什么这个脚本没有按预期工作。这是一个简单的脚本,我试图在其中导入 CSV,select 我想要的几列,然后导出 CSV 并复制自身。 (基本上我们已经归档了数据,由于内存大小限制,我只需要从另一个项目中提取几列)。这个脚本非常简单,它显然与它在不起作用时造成的挫败感成反比关系……现在的最终结果是我得到一个空的 csv,而不是只包含列的 csv selected with Select-Object.
$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
}
正如 Matt 评论的那样,您的最后一个 $PSItem ($_)
不再与 Get-ChildItem
相关,而是与没有 FullName
[=23= 的 Select-Object
cmdlet 相关]
您可以使用不同的 foreach 方法:
$RootPath = "D:\SomeFolder"
$csvFilePaths = Get-ChildItem $RootPath -Recurse -Include *.csv
foreach ($csv in $csvFilePaths)
{
Import-CSV $csv.FullName |
Select-Object Test_Name,Test_DataName,Device_Model,Device_FW,Data_Avg_ms,Data_StdDev |
Export-Csv $csv.FullName -NoType -Force
}
或者保留您的代码,添加 $CsvPath
包含 csv 路径的变量,稍后使用它:
$RootPath = "D:\SomeFolder"
Get-ChildItem $RootPath -Recurse -Include *.csv | ForEach-Object{
$CsvPath = $_.FullName
Import-CSV $CsvPath |
Select-Object Test_Name,Test_DataName,Device_Model,Device_FW,Data_Avg_ms,Data_StdDev |
Export-Csv $CsvPath -NoType -Force
}
除非您预先完整地将输入文件读入内存,否则您无法在给定管道中安全地读取和写回同一文件.
具体来说,Import-Csv file.csv | ... | Export-Csv file.csv
这样的命令会擦除file.csv
的内容。
最简单的解决方案是将读取输入文件的命令附在(...)
中,但要注意:
文件的内容(转化为objects)必须整体装入内存 .
如果管道在所有(已转换的)object 被写回到文件.
应用于您的命令:
$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 file-info objects。您尝试通过 $csvFilePaths = ...
收集文件路径的尝试不起作用,因为它试图收集 Export-Csv
的 输出,但 Export-Csv
没有产生输出。
此外,为了安全起见,我已将 Import-Csv
参数从 $_
更改为 $_.FullName
以确保 Import-Csv
找到输入文件(因为,很遗憾, file-info object $_
绑定为 字符串,有时 扩展为 仅仅是文件名).
一个更安全的解决方案是先输出到一个临时文件,并且(仅)在成功完成后替换原始文件。
无论采用哪种方法,替换文件都将具有默认文件属性和权限;如果原始文件具有您要保留的特殊属性 and/or 权限,则必须明确地重新创建它们。
所以我想通了。我试图直接通过 Import-Csv cmdlet 进行管道传输,而不是将其声明为 o.g 中的变量。代码。这是实现我想要完成的任务的代码片段。我之前试图直接在 Import-Csv cmdlet 中进行管道传输,我只需要声明一个使用 Import-Csv cmdlet 作为其定义的变量,并将该变量通过管道传输到 Select-Object,然后是 Export-Csv cmdlet。谢谢大家的帮助,我很感激!
$RootPath = "\someDirectory\"
$CsvFilePaths = @(Get-ChildItem $RootPath -Recurse -Include *.csv)
$ColumnsWanted = @('Test_Name','Test_DataName','Device_Model','Device_FW','Data_Avg_ms','Data_StdDev')
for($i=0;$i -lt $CsvFilePaths.Length; $i++){
$csvPath = $CsvFilePaths[$i]
Write-Host $csvPath
$importedCsv = Import-CSV $csvPath
$importedCsv | Select-Object $ColumnsWanted | Export-CSV $csvPath -NoTypeInformation
}
我费了好大的劲才弄明白为什么这个脚本没有按预期工作。这是一个简单的脚本,我试图在其中导入 CSV,select 我想要的几列,然后导出 CSV 并复制自身。 (基本上我们已经归档了数据,由于内存大小限制,我只需要从另一个项目中提取几列)。这个脚本非常简单,它显然与它在不起作用时造成的挫败感成反比关系……现在的最终结果是我得到一个空的 csv,而不是只包含列的 csv selected with Select-Object.
$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
}
正如 Matt 评论的那样,您的最后一个 $PSItem ($_)
不再与 Get-ChildItem
相关,而是与没有 FullName
[=23= 的 Select-Object
cmdlet 相关]
您可以使用不同的 foreach 方法:
$RootPath = "D:\SomeFolder"
$csvFilePaths = Get-ChildItem $RootPath -Recurse -Include *.csv
foreach ($csv in $csvFilePaths)
{
Import-CSV $csv.FullName |
Select-Object Test_Name,Test_DataName,Device_Model,Device_FW,Data_Avg_ms,Data_StdDev |
Export-Csv $csv.FullName -NoType -Force
}
或者保留您的代码,添加 $CsvPath
包含 csv 路径的变量,稍后使用它:
$RootPath = "D:\SomeFolder"
Get-ChildItem $RootPath -Recurse -Include *.csv | ForEach-Object{
$CsvPath = $_.FullName
Import-CSV $CsvPath |
Select-Object Test_Name,Test_DataName,Device_Model,Device_FW,Data_Avg_ms,Data_StdDev |
Export-Csv $CsvPath -NoType -Force
}
除非您预先完整地将输入文件读入内存,否则您无法在给定管道中安全地读取和写回同一文件.
具体来说,Import-Csv file.csv | ... | Export-Csv file.csv
这样的命令会擦除file.csv
的内容。
最简单的解决方案是将读取输入文件的命令附在(...)
中,但要注意:
文件的内容(转化为objects)必须整体装入内存 .
如果管道在所有(已转换的)object 被写回到文件.
应用于您的命令:
$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 file-info objects。您尝试通过 $csvFilePaths = ...
收集文件路径的尝试不起作用,因为它试图收集 Export-Csv
的 输出,但 Export-Csv
没有产生输出。
此外,为了安全起见,我已将 Import-Csv
参数从 $_
更改为 $_.FullName
以确保 Import-Csv
找到输入文件(因为,很遗憾, file-info object $_
绑定为 字符串,有时 扩展为 仅仅是文件名).
一个更安全的解决方案是先输出到一个临时文件,并且(仅)在成功完成后替换原始文件。
无论采用哪种方法,替换文件都将具有默认文件属性和权限;如果原始文件具有您要保留的特殊属性 and/or 权限,则必须明确地重新创建它们。
所以我想通了。我试图直接通过 Import-Csv cmdlet 进行管道传输,而不是将其声明为 o.g 中的变量。代码。这是实现我想要完成的任务的代码片段。我之前试图直接在 Import-Csv cmdlet 中进行管道传输,我只需要声明一个使用 Import-Csv cmdlet 作为其定义的变量,并将该变量通过管道传输到 Select-Object,然后是 Export-Csv cmdlet。谢谢大家的帮助,我很感激!
$RootPath = "\someDirectory\"
$CsvFilePaths = @(Get-ChildItem $RootPath -Recurse -Include *.csv)
$ColumnsWanted = @('Test_Name','Test_DataName','Device_Model','Device_FW','Data_Avg_ms','Data_StdDev')
for($i=0;$i -lt $CsvFilePaths.Length; $i++){
$csvPath = $CsvFilePaths[$i]
Write-Host $csvPath
$importedCsv = Import-CSV $csvPath
$importedCsv | Select-Object $ColumnsWanted | Export-CSV $csvPath -NoTypeInformation
}