CSV grep但保留标题

时间:2012-10-25 15:52:23

标签: linux csv awk grep

我有一个看起来像这样的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下工作

3 个答案:

答案 0 :(得分:4)

使用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替换为您要检查的列的相应名称。

答案 1 :(得分:1)

$ 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 - 如果有必要,代码将更清晰,更容易增强。

答案 2 :(得分:0)

您可以使用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>2,您可以添加量词:

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

其中M=n-1。量词只是意味着重复,所以非逗号-0或更多次逗号的事情重复M次。

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