刪除包含 0 次數超過「x」次的行

刪除包含 0 次數超過「x」次的行

我有一個很大的逗號分隔文件。我需要過濾掉包含 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

相關內容