34

我必须合并具有相同标题的多个 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

此代码将完美地合并文件,但由于我需要第一个文件的标题,这不会给我标题。

我应该怎么办?

4

4 回答 4

77
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;}' 说,“如果它是当前文件的第一行,则跳过这一行,并且至少有 1 行已被整体读取。” 这具有打印第一个文件的 CSV 标题而在其余部分跳过它的效果。

链接了解之间的区别

于 2013-06-03T05:52:25.910 回答
1

如果 Perl 是一个选项:

perl -ne 'print if $. > 1 or ! $h; $h=1; close ARGV if eof' *.csv > master.csv

$.是行号。
它不会在文件之间自动重置,因此close ARGV if eof需要。
$h记录是否已经打印了标题。

于 2015-11-12T23:54:44.430 回答
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) 或 die("无法关闭 php://output"); ?>

于 2017-03-08T11:20:23.880 回答
0

就像每个使用该线程的公认解决方案的人的旁注一样(像我一样:)) - 请注意,如果标题包含新行,则此代码将失败,即类似

column1,"column\nwith\new line",column2
value1,value2,value3
...

在这种情况下,只有部分column1,"column将被视为标题,而标题的其余部分将被视为正常行(这将完全破坏您的最终 CSV)。如果您有一个带有新行的标题,我能想到的唯一解决方案是使用能够正确读取标题的“成熟”的 c​​sv 阅读器库。

但是尽管有这个小问题,上面的那行让我免于头痛。:D

于 2020-10-29T19:32:56.037 回答