【问题标题】:CSV grep but keep the headerCSV grep 但保留标题
【发布时间】:2012-10-25 15:52:23
【问题描述】:

我有一个如下所示的 CSV 文件:

A,B,C
1,2,3
4,4,4
1,2,6
3,6,9

有没有一种简单的方法来grep B 列为2 的所有行,并保留标题?例如,我希望输出像

A,B,C
1,2,3
1,2,6

我在linux下工作

【问题讨论】:

    标签: linux csv awk grep


    【解决方案1】:

    使用 awk:

    awk -F, 'NR==1 || $2==2' file
    

    NR==1 -> 如果是第一行, $2==2 -> 如果第二列等于 2。如果以上任何一个为真,则打印行。

    使用标题列名称选择列:

    awk -F, -v col="B" 'NR==1{for(i=1;i<=NF;i++)if($i==col)break;print;next}$i==2'  file
    

    将 B 替换为您要检查的列的适当名称。

    【讨论】:

    • 感谢大师,但是有没有办法用标题列名称替换 $2 ?我的 CSV 有很多列,所以很难计算......
    • @CodeNoob:更新了上面的解决方案。
    【解决方案2】:

    您可以使用sed中的地址:

    sed -n '1p;/^[^,]*,2/p'
    

    意思是:

    1p        Print the first line.
    /         Start a match.
        ^     Match the beginnning of a line.
        [^,]  Match anything but a comma
        *     zero or more times.
        ,     Match a comma.
        2     Match a 2.
    /p        End of match, if it matches, print.
    

    如果标头可以包含您要查找的值,则应更加小心:

    sed -n '1p;1!{/^[^,]*,2/p}'
    

    1!{ ... } 仅表示“对第一行以外的行执行以下操作”。

    对于列号n&gt;2,可以加一个量词:

    sed -n '1p;1!{/^\([^,]*,\)\{M\}2/p}'
    

    在哪里M=n-1。量词只是表示重复,所以 non-comma-0-or-more-times-comma 的东西重复了 M 次。

    对于值可以包含逗号的真正 CSV 文件,切换到 Perl 和 Text::CSV

    【讨论】:

    • 谢谢 choroba,但你能帮我翻译一下吗?我只是看到很多奇怪的字符,但不知道它们是什么意思
    【解决方案3】:
    $ awk -F, 'NR==1 { for (i=1;i<=NF;i++) h[$i] = i; print; next } $h["B"] == 2' file
    A,B,C
    1,2,3
    1,2,6
    

    顺便说一句,sed 是在单行上进行简单替换的出色工具,对于其他任何事情,只需使用 awk - 如果需要,将来代码会更清晰,并且更容易增强。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-23
      • 2018-12-27
      • 1970-01-01
      • 2016-05-08
      • 2015-02-04
      相关资源
      最近更新 更多