【问题标题】:Merge csv files with same header: passing multiple files to awk with xargs合并具有相同标题的 csv 文件:使用 xargs 将多个文件传递给 awk
【发布时间】:2018-10-22 01:45:28
【问题描述】:

我需要将目录中具有相同标题(第一行)的所有 csv 文件合并在一起。假设我们有:

文件 a.txt:

head1,head2,head3
1,2,"abc"
8,42,"def"

文件 b.txt:

head4,head2
"aa",2

文件 c.txt:

head1,head2,head3
12,2,"z"
15,2,"z"

如果我想要所有标题为“head1,head2,head3”的文件,那么它应该合并文件 a 和 c 并生成:

awk 'FNR==1 && NR!=1{next;}{print}' a.txt c.txt 
head1,head2,head3
1,2,"abc"
8,42,"def"
12,2,"z"
15,2,"z"

现在,对于给定的标头,我可以检测要自动合并的文件,但我无法将结果列表传递给 awk。我正在使用以下命令:

head -n1 -v * | grep -B1 "head1,head2,head3" | awk "/==>/{ print \$2 }" | xargs -l -0 awk 'FNR==1 && NR!=1{next;}{print}'
awk: fatal: cannot open file `a.txt
c.txt
' for reading (No such file or directory)

其中head 列出文件名和第一行,grep 仅保留匹配的标头(以及前行中使用 -B1 关联的文件名),第一次调用 awk 仅保留文件名称,每行一个。 我也试过了(添加tr '\n' ' '):

head -n1 -v * | grep -B1 "head1,head2,head3" | awk "/==>/{ print \$2 }" | tr '\n' ' ' | xargs -l -0 awk 'FNR==1 && NR!=1{next;}{print}'                       
awk: fatal: cannot open file `a.txt c.txt ' for reading (No such file or directory)

我最终尝试了以下方法(改用tr '\n' '\0'):

head -n1 -v * | grep -B1 "head1,head2,head3" | awk "/==>/{ print \$2 }" | tr '\n' '\0' | xargs -l -0 awk 'FNR==1 && NR!=1{next;}{print}'                            
head1,head2,head3
1,2,"abc"
8,42,"def"
head1,head2,head3
12,2,"z"
15,2,"z"

(虽然我不确定\0 是如何解释的),至少这个命令可以工作,但看起来每个文件都是由 awk 单独处理的,因为标题被打印了两次。

我错过了什么?

【问题讨论】:

    标签: csv awk xargs


    【解决方案1】:

    这有帮助吗?

    $ awk -v h='head1,head2,head3' 'BEGIN{print h} FNR==1{f=$0==h?1:0; next} f' *.txt
    head1,head2,head3
    1,2,"abc"
    8,42,"def"
    12,2,"z"
    15,2,"z"
    
    • -v h='head1,head2,head3' 保存标题行以签入变量 h
    • BEGIN{print h} 打印标题(假设至少有一个文件匹配)
    • FNR==1{f=$0==h?1:0; next} 根据h 的文件匹配内容的第一行设置/清除标志
    • f 如果设置了标志,则打印
    • *.txt 要合并的文件列表


    使用 GNU awk,您可以使用 FNR==1{if($0!=h) nextfile; next} 1 跳过不必要地读取不匹配的文件

    【讨论】:

    • 完美,谢谢!我认为可能有一个更简单的解决方案,但我担心它会更昂贵,因为它需要比较所有行。跳过带有不匹配标题的文件对我来说似乎是一个不错的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-15
    • 2023-02-08
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    相关资源
    最近更新 更多