
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,0
Trennzeichen, was vierFelderinsgesamt. Wenn Sie awk -F',0' 'NF<5 {print}'
stattdessen verwenden, sollten Sie in der Ausgabe die richtigen Zeilen sehen.
,0
stimmt 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 awk
das Wortgrenzen unterstützt \<...\>
, könnten Sie
gawk 'gsub(/\<0\>/, "0") <5' infile