问题:1("FileName";在字符串中,2(录制7000多个文件花了一个多小时。如何使录制速度更快?
Get-ChildItem "C:*.csv" | ForEach-Object {
$CSV = Import-CSV -Path $_.FullName
$FileName = $_.Name
$CSV | Select-Object *,@{N='Filename';E={$FileName}} | Export-CSV $_.FullName
}
仅使用PowerShell代码加快速度的唯一方法是采用纯文本处理:
Get-ChildItem C:*.csv | ForEach-Object {
$fileName = $_.Name
$toAppend = ',"Filename"'
$isHeaderRow = $true
$lines = switch -File $_.FullName {
default {
$_ + $toAppend # append to the line and output
if ($isHeaderRow) {
$isHeaderRow = $false
$toAppend = ',"{0}"' -f $fileName
}
}
}
# Write the updated lines back to the file.
# Adjust the -Encoding argument as needed.
Set-Content $_.FullName -Value $lines -Encoding utf8 -WhatIf
}
注意:上面命令中的-WhatIf
公共参数预览操作。一旦您确定操作将执行您想要的操作,请删除-WhatIf
注:
带有-File
参数的switch
语句是逐行处理文本文件的有效方法。
请注意,更新行的数组$lines
通过-Value
参数传递给Set-Content
,这比使用管道($lines | Set-Content ...
(要快得多
该代码假设单个CSV文件可以作为一个整体放入内存;如果这不可能,您将不得不切换到基于管道的解决方案,这将减慢速度:& { switch ... } | Set-Content ...
变体,其中所有输入文件都具有相同的列结构并且将被合并为单个输出文件:
$outFile = './out.csv' # single output file
$null = New-Item $outFile # initialize it (create it empty)
$firstFile = $true
Get-ChildItem C:*.csv | ForEach-Object {
$fileName = $_.Name
$isHeaderRow = $true
$lines = switch -File $_.FullName {
default {
if ($isHeaderRow) {
$isHeaderRow = $false
if ($firstFile) {
$firstFile = $false
$_ + ',"Filename"' # output single header row
}
# Construct string to append to this file's data rows.
$toAppend = ',"{0}"' -f $fileName
} else { # data row
$_ + $toAppend # append to the line and output
}
}
}
# Append this file's updated lines to the output file.
# Adjust the -Encoding argument as needed.
Add-Content $outFile -Value $lines -Encoding utf8 -WhatIf
}