Löschen Sie eine Zeile, die 0 mehr als 'x' Mal enthält

Löschen Sie eine Zeile, die 0 mehr als 'x' Mal enthält

Ich habe eine große, durch Kommas getrennte Datei. Ich muss Zeilen herausfiltern, die x Spalten mit Nullen enthalten (ausschließlich der ersten Zeile). Der Einfachheit halber nehmen wir an, ich möchte Zeilen mit mehr als 4 Nullen herausfiltern:

    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

Würde zurückkehren:

    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“ herausfiltern.

Folgendes habe ich versucht (ich habe versucht, „,0“ als Trennzeichen zu verwenden, was mir jedoch nicht gelungen ist):

awk -F',0' 'NF<4 {print}' file.csv

Antwort1

Mit werden awk -F',0'drei Kopien von als drei,0Trennzeichen, was vierFelderinsgesamt. Wenn Sie awk -F',0' 'NF<5 {print}'stattdessen verwenden, sollten Sie in der Ausgabe die richtigen Zeilen sehen.

,0stimmt auch mit Zeichenfolgen wie überein 213,0123, die Sie möglicherweise als Nulltrennzeichen verwenden möchten oder nicht.

Sie können es also auch ,als Feldtrennzeichen verwenden und die Felder zählen, die nur diese eine Null enthalten:

awk -F, '{z=0; for (i = 1 ; i <= NF ; i++) if ($i == 0) z++} z <= 4' file.csv

Antwort2

Sie können Ihr Problem auch mithilfe von regulären Ausdrücken und lösen grep.

grep -Ev '(,0(,[^0,]+)*){4,}' file.csv

Ich habe es mit dieser Datei getestet:

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

Es gibt einige Annahmen:

  • keine Zahl ungleich Null beginnt mit einer Null,
  • Nullzahlen enthalten nur eine Null,
  • alle Zahlen sind ganze Zahlen.

Der reguläre Ausdruck könnte bei Bedarf erweitert werden, um solche Fälle abzudecken.

Antwort3

KISS-Ansatz mitawk

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

Mitperl

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

Antwort4

Wenn alle Zahlen ganzzahlig sind, dann mitGNU awkdas Wortgrenzen unterstützt \<...\>, könnten Sie

gawk 'gsub(/\<0\>/, "0") <5' infile

verwandte Informationen