【发布时间】: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下工作
【问题讨论】:
我有一个如下所示的 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下工作
【问题讨论】:
使用 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 替换为您要检查的列的适当名称。
【讨论】:
您可以使用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。量词只是表示重复,所以 non-comma-0-or-more-times-comma 的东西重复了 M 次。
对于值可以包含逗号的真正 CSV 文件,切换到 Perl 和 Text::CSV。
【讨论】:
$ 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 - 如果需要,将来代码会更清晰,并且更容易增强。
【讨论】: