我必须合并多个具有相同标头的CSV文件。 我必须保留第一个文件的标题并删除所有其他文件的标题并合并它们并创建一个主文件。
文件1:
Id,city,name ,location
1,NA,JACK,CA
文件2:
ID,city,name,location
2,NY,JERRY,NY
输出:
Id,city,name,location
1,NA,JACK,CA
2,NY,JERRY,NY
目前我正在使用此代码:
ls *.csv | xargs -n 1 tail -n+2 > master.csv
此代码将完美合并文件,但由于我需要第一个文件的标题,这不会给我标题。
我该怎么办?
答案 0 :(得分:59)
awk 'FNR==1 && NR!=1{next;}{print}' *.csv
在solaris unix上测试:
> cat file1.csv
Id,city,name ,location
1,NA,JACK,CA
>
> cat file2.csv
ID,city,name,location
2,NY,JERRY,NY
>
> nawk 'FNR==1 && NR!=1{next;}{print}' *.csv
Id,city,name ,location
1,NA,JACK,CA
2,NY,JERRY,NY
>
kevin-d给出的解释:
之间的差异FNR是当前文件中到目前为止读取的行数(记录)。 NR是整体读取的行数。所以条件'FNR == 1&& NR!= 1 {next;}'说,“如果它是第一行,则跳过这一行 当前文件,至少有一行已被读取。“这有 跳过时打印第一个文件的CSV标题的效果 其余的。
答案 1 :(得分:0)
如果Perl是一个选项:
perl -ne 'print if $. > 1 or ! $h; $h=1; close ARGV if eof' *.csv > master.csv
$.
是行号
它不会在文件之间自动重置,因此需要close ARGV if eof
$h
记录是否已打印标题。
答案 2 :(得分:0)
<?php
ini_set('auto_detect_line_endings', true);
$dir = "include/*.csv";
$returnVal = array();
foreach (glob($dir) as $file) {
$header = null;
$file = fopen($file, 'r') or die('Unable to open file!');
while(($row = fgetcsv($file)) !== false){
if($header === null){
$header = $row;
continue;
}
$newRow = array();
for($i = 0; $i<count($row); $i++){
$newRow[] = $row[$i];
}
if($newRow[0] == null)
break;
else
$returnVal[] = $newRow;
}
fclose($file);
}
//var_dump($returnVal);
$output = fopen("file.csv",'w') or die("Can't open output");
fputcsv($output, array('Date','close','open'));
foreach($returnVal as $product) {
fputcsv($output, $product);
}
fclose($ output)或死(&#34;不能关闭php://输出&#34;); ?&GT;
答案 3 :(得分:0)
仅对使用此线程的公认解决方案的每个人(也与我一样:)作为一个补充说明)-请注意,如果标头包含新行(例如,类似
),则此代码将失败column1,"column\nwith\new line",column2
value1,value2,value3
...
在这种情况下,只有column1,"column
部分将被视为标题,而标题的其余部分将被视为普通行(这将完全破坏您的最终CSV)。如果您的标题中包含换行符,那么我能想到的唯一解决方案是使用“完整”的csv阅读器库,该库将能够正确读取标题。
但是,尽管有这个小问题,上面的内容还是使我免于头痛。 :D