假设我有两个csv文件。一个是
id_number,location_code,category,animal,quantity
12212,3,4,cat,2
29889,7,6,dog,2
98900,
33221,1,8,squirrel,1
第二个是:
98900,2,1,gerbil,1
第二个文件的末尾可能会有换行符或其他内容(也许没有,我没有检查过),但只有一行内容。可能有三个或四个或更多个不同的“第二个”文件变体,但是每个文件都将具有一个第一元素(在本示例中为98900),该元素与该文件中的不完整行相对应,类似于本示例中的内容。 / p>
有没有一种方法可以使用powershell自动将第二个(以及其他任何类似的)csv文件中的行合并到第一个文件的匹配行中,从而使结果文件为:
12212,3,4,cat,2
29889,7,6,dog,2
98900,2,1,gerbil,1
33221,1,8,squirrel,1
答案 0 :(得分:1)
这是一个简单的解决方案,假设总是存在一个完全匹配的项目,并且您不关心输出顺序。将输出路径更改为csv1以覆盖。
我在两个输入文件中手动添加了标题,但是如果您不想更改文件,则可以在Import-Csv中指定它们。
[array]$MissingLine = Import-Csv -Path "C:\Users\me\Documents\csv2.csv"
[string]$MissingId = $MissingLine[0].id_number
[array]$BigCsv = Import-Csv -Path "C:\Users\me\Documents\csv1.csv" |
Where-Object {$_.id_number -ne $MissingId}
($BigCsv + $MissingLine) |
Export-Csv -Path "C:\Users\me\Documents\Combined.csv"
答案 1 :(得分:1)
main.csv
id_number,location_code,category,animal,quantity
12212,3,4,cat,2
29889,7,6,dog,2
98900,
33221,1,8,squirrel,1
correction_001.csv
98900,2,1,gerbil,1
在命令行或您选择的.ps1文件中使用的合并代码
$myHeader = @('id_number','location_code','category','animal','quantity')
#Stage all the correction files: last correction in the most recent file wins
$ToFix = @{}
filter Plumbing_Import-Csv($Header){import-csv -LiteralPath $_ -Header $Header}
ls correction*.csv | sort -Property LastWriteTime | Plumbing_Import-Csv $myHeader | %{$ToFix[$_.id_number]=$_}
function myObjPipe($Header){
begin{
function TextTo-CsvField([String]$text){
#text fields which contain comma, double quotes, or new-line are a special case for CSV fields and need to be accounted for
if($text -match '"|,|\n'){return '"'+($text -replace '"','""')+'"'}
return $text
}
function myObjTo-CsvRecord($obj){
return ''+
$obj.id_number +','+
$obj.location_code +','+
$obj.category +','+
(TextTo-CsvField $obj.animal)+','+
$obj.quantity
}
$Header -join ','
}
process{
if($ToFix.Contains($_.id_number)){
$out = $ToFix[$_.id_number]
$ToFix.Remove($_.id_number)
}else{$out = $_}
myObjTo-CsvRecord $out
}
end{
#I assume you'd append any leftover fixes that weren't used
foreach($out in $ToFix.Values){
myObjTo-CsvRecord $out
}
}
}
import-csv main.csv | myObjPipe $myHeader | sc combined.csv -encoding ascii
您也可以使用ConvertTo-Csv
,但我的首选是不要拥有所有额外的"
杂物。
编辑1:减少代码冗余,占\n
,固定附加内容,并使用有关-Header commandlet参数的@OwlsSleeping建议
也适用于以下文件:
correction_002.csv
98900,2,1,I Win,1
correction_new.csv
98901,2,1,godzilla,1
correction_too.csv
98902,2,1,gamera,1
98903,2,1,mothra,1
编辑2:将gc | ConvertTo-Csv
转换为Import-Csv
,以解决前端\n
问题。现在也可以使用:
correction_003.csv
29889,7,6,"""bad""
monkey",2