2011-06-22 70 views
3

我有一个.csv文件,其标题行像这样;csv文件过滤

headerA,headerB,headerC 
bill,jones,p 
mike,smith,f 
sally,silly,p 

我想在headerC列中过滤掉任何具有f值的记录。

我可以用sed或awk做到吗?

+2

注意,[CSV](http://tools.ietf.org/html/rfc4180)可以包含嵌入的换行符,所以任何纯的基于行的解决方案可能做错误的东西与某些投入。此外,引用的值可能会带来许多天真的解决方法问题。 – Joey

+1

@Joey,对。通常的建议是使用带有专用CSV库的语言,如[Perl](http://search.cpan.org/~makamaka/Text-CSV-1.21/lib/Text/CSV.pm) –

回答

2

好,如果你知道headerC始终是在第三列,以下sed命令将工作:

sed -r '/[^,]+(,[^,]+){1},f/ d' <file.csv> filefiltered.csv

而下面的awk命令不相同:

awk 'BEGIN {FS=","} {if($3 != "f") print}' file.csv

如果你不知道headerC总是在特定的列中,它会变得更棘手。这是否工作?

+0

awk命令可以简化:'awk -F,'$ 3!=“f”'file.csv' –

+0

但是如果头部在第三列只有一个“f”,它将不会打印标题行... –

+1

@glenn it的确可以。但是如果-F是一个GNU扩展名,我从来没有打扰过,所以我只是最安全的。我会认为它不是:) –

-2

不需要awk或者sed,这可以通过像切割和grep更简单的命令来完成管道连接到一起这样

cut -d"," -f 3| grep -i f 

我假定分隔符是昏迷和C列THRID之一。如果它没有适当地改变上面的值。我已经使用grep与我的选项,以便它忽略大小写。如果只想匹配lowercse f或upppercase f,则删除i选项并相应地更改它。

+1

这将只输出第三个字段的值,而不是整行。 –

1

有点不清楚,这是你要求的吗?

$ awk -F, '{ if($3 == "f")print}' input 
mike,smith,f 

有了一个标题和格式使用column

$ awk -F, '{ if (NR == 1)print}{if($3 == "f")print}' input | column -t -s, 
headerA headerB headerC 
mike  smith f 
7

如果标题不仅包含f在第三列名:

sed '/,f$/d' FILE 

会做(删除每一行从输入如果以,f结尾)。

如果有,我会去用:

sed -n -e '1p;/,[^f]$/p' FILE 

(不打印默认情况下(-n),但第一行必须1p任何东西,如果线与其他字符比f结束。 .. 注:这是不行的,如果第三columnc包含一个以上的字符)

而一个awk之一:

awk -F, 'NF == 1 ; NF > 1 && $3 != "f"' FILE 

(总是打印第一行(NF == 1为真,然后是默认操作,即print $0,则下一个条件是检查我们是否已经超过第一行,并且第三个字段不是f,则默认操作.. )

HTH

+1

如果第三列包含> 1个字符,则您的第二个sed解决方案将中断。更好地坚持使用第一个sed或awk,因为它更精确地实现了需求(删除行,如果“f”) –

+0

根据“规范”:“我想筛选出任何带有f值的记录在headerC列“。 所以这是正确的国际海事组织。 –

+1

如果第三列包含“ab”,那不匹配'/,[^ f] $ /',所以它会被过滤。用于awk解决方案的 –

1

grep作品,看看例子。

grep ",.*,.*f" << EOF 
headerA,headerB,headerC 
bill,josef,p 
mike,smith,f 
sally,silly,p 
EOF 

输出:

mike,smith,f 
+0

不错,干净而快捷(不需要最终的*。) –