我需要从目录中获取一系列csv文件,并将它们放入Powershell中的数组中(最终操作并写回csv)。
问题是有5种文件类型。我需要大约8列从每个。这些列本质上是相同的,只是标题不同。
是否有简单的方法来做到这一点?我开始用我的8个字段创建一个自定义对象,遍历导入每个字段的文件,查看文件名(它告诉我需要的列名),然后将一堆if添加到我的自定义对象数组中。
我想知道是否有更简单的方法…就像使用模板来说明每个文件中的哪些列。
最后这样做了。它可能不是最有效的,但有效。我最后把每个文件分别写出来,最后再合并,因为PS真的陷入了困境(合并了100多万行)。
$Newcsv = @()
$path = "c:scrapBWFILES"
$files = gci -path $path -recurse -filter *.csv | Where-Object { ! ($_.psiscontainer) }
$counter=1
foreach($file in $files)
{
$csv = Import-Csv $file.FullName
if ($file.Name -like '*SAV*')
{
$Newcsv = $csv | Select-Object @{Name="PRODUCT";Expression={"SV"}},DMBRCH,DMACCT,DMSHRT
}
if ($file.Name -like '*TIME*')
{
$Newcsv = $csv | Select-Object @{Name="PRODUCT";Expression={"TM"}},TMBRCH,TMACCT,TMSHRT
}
if ($file.Name -like '*TRAN*')
{
$Newcsv = $csv | Select-Object @{Name="PRODUCT";Expression={"TR"}},DMBRCH,DMACCT,DMSHRT
}
if ($file.Name -like '*LN*')
{
$Newcsv = $csv | Select-Object @{Name="PRODUCT";Expression={"LN"}},LNBRCH,LNNOTE,LNSHRT
}
$Newcsv | Export-Csv "C:scrap$file.name$counter.csv" -force -notypeinformation
$counter++
}
get-childItem "c:scrap*.csv" | foreach {
$filePath = $_
$lines = $lines = Get-Content $filePath
$linesToWrite = switch($getFirstLine) {
$true {$lines}
$false {$lines | Select -Skip 1}
}
$getFirstLine = $false
Add-Content "c:scrapcombined.csv" $linesToWrite
}
使用哈希表作为参考,进行一点RegEx匹配,并在ForEach-Object
循环中使用自动变量$Matches
(别名%
使用),这些都可以缩短为:
$path = "c:scrapBWFILES"
$Reference = @{
'SAV' = 'SV'
'TIME' = 'TM'
'TRAN' = 'TR'
'LN'='LN'
}
Set-Content -Value "PRODUCT,BRCH,ACCT,SHRT" -Path 'c:scrapcombined.csv'
gci -path $path -recurse -filter *.csv | Where-Object { !($_.psiscontainer) -and $_.Name -match ".*(SAV|TIME|TRAN|LN).*"}|%{
$Product = $Reference[($Matches[1])]
Import-CSV $_.FullName | Select-Object @{Name="PRODUCT";Expression={$Product}},*BRCH,@{l='Acct';e={$_.LNNOTE, $_.DMACCT, $_.TMACCT|?{$_}}},*SHRT | ConvertTo-Csv -NoTypeInformation | Select -Skip 1 | Add-Content 'c:scrapcombined.csv'
}
应该产生完全相同的文件。唯一有点棘手的部分是LNNOTE/TMACCT/DMACCT字段,因为显然您不能像*SHRT.