2011-06-22 67 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

不錯,乾淨而快捷(不需要最終的*。) –