
我有一個很大的逗號分隔文件。我需要過濾掉包含 x 個包含零的列(不包括第一行)的行。為簡單起見,假設我想過濾掉包含超過 4 個零的行:
gene,v1,v2,v3,v4,v5,v6,v7
gene1,0,1,5,0,0,4,100
gene2,1,0,0,0,5,210,2
gene3,0,0,0,0,6,0,0
將返回:
gene,v1,v2,v3,v4,v5,v6,v7
gene1,0,1,5,0,0,4,100
gene2,1,0,0,0,5,210,2
過濾掉“gene3”。
這是我嘗試過的(嘗試使用 ',0' 作為分隔符號但失敗):
awk -F',0' 'NF<4 {print}' file.csv
答案1
,awk -F',0'
的三份,0
將被視為三份分隔符,給出四個領域總共。因此,如果您使用awk -F',0' 'NF<5 {print}'
它,您應該在輸出中看到正確的行。
,0
還將匹配諸如 之類的字串213,0123
,您可能想也可能不想將其用作零分隔符號。
因此,您也可以用作,
欄位分隔符號並計算僅包含一個零的欄位:
awk -F, '{z=0; for (i = 1 ; i <= NF ; i++) if ($i == 0) z++} z <= 4' file.csv
答案2
您也可以使用正規表示式和grep
.
grep -Ev '(,0(,[^0,]+)*){4,}' file.csv
我在這個文件上測試了它:
gene,v1,v2,v3,v4,v5,v6,v7
gene1,0,1,5,0,0,4,100
gene2,1,0,0,0,5,210,2
gene3,0,0,0,0,6,0,0
gene4,0,0,0,4,6,0,0
gene5,0,1,0,4,6,0,0
有一些假設:
- 沒有以零開頭的非零數字,
- 零數只包含一個零,
- 所有數字都是整數。
如果您需要,可以擴展正規表示式來解決此類情況。
答案3
KISS 方法,awk
awk -F, '{c = 0; for(i=1; i<=NF; i++) {c += $i == "0" ? 1 : 0}} c <= 3' file.csv
gene,v1,v2,v3,v4,v5,v6,v7
gene1,0,1,5,0,0,4,100
gene2,1,0,0,0,5,210,2
和perl
perl -F, -ne 'print unless (grep { $_ eq "0" } @F) > 3' file.csv
gene,v1,v2,v3,v4,v5,v6,v7
gene1,0,1,5,0,0,4,100
gene2,1,0,0,0,5,210,2
答案4
如果所有數字都是整數,則使用GNU awk
它支援單字邊界\<...\>
,你可以這樣做
gawk 'gsub(/\<0\>/, "0") <5' infile