Zählen Sie die Anzahl der Zeilen mit einer bestimmten Anzahl von Spalten

Zählen Sie die Anzahl der Zeilen mit einer bestimmten Anzahl von Spalten

Ich habe mehrere Dateien mit folgendem Inhalt:

GGHTERR_01218   GGHTERR_02418   GGHTERR_01991
GGHTERR_02211   GGHTERR_02297   GGHTERR_02379
GGHTERR_02294   GGHTERR_02455   GGHTERR_02374
GGHTERR_00532   GGHTERR_00534
GGHTERR_00533   GGHTERR_00535
GGHTERR_00776   GGHTERR_00779
GGHTERR_01220   GGHTERR_01620
GGHTERR_01760   GGHTERR_01761
GGHTERR_01774   GGHTERR_02404
GGHTERR_01889   GGHTERR_01890
GGHTERR_02081   GGHTERR_02287
GGHTERR_02152   GGHTERR_02153
GGHTERR_02260   GGHTERR_02321
GGHTERR_02295   GGHTERR_02375
GGHTERR_02419   GGHTERR_02437
GGHTERR_02420   GGHTERR_02438
GGHTERR_02430   GGHTERR_02448
GGHTERR_00001
GGHTERR_00002
GGHTERR_00003
GGHTERR_00004
GGHTERR_00005
GGHTERR_00006
GGHTERR_00007

Ich würde gerne wissen, ob es eine einfache Möglichkeit gibt, die Anzahl der Zeilen mit 3 Spalten, 2 Spalten und 1 Spalte zu zählen.

Die Ausgabe sollte also etwa so aussehen:

3 columns: 3
2 columns: 14
1 colums: 7

Antwort1

Awk ist dafür perfekt geeignet. Es trennt Zeilen an Leerzeichen (standardmäßig; kann mit der -FOption geändert werden) und die interne Variable NF(Anzahl der Felder) enthält die Anzahl der Felder pro Zeile. Gehen Sie also einfach die Datei durch und speichern Sie NFfür jede Zeile:

awk '{ 
        nums[NF]++
     }
     END{
        for(num in nums){
            printf "%d columns: %d\n", num, nums[num]
        }
     }' file

Der obige Code speichert einfach die Anzahl der Felder ( NF) im assoziativen Array, numsdessen Schlüssel die Anzahl der Felder und dessen Werte die Anzahl der Vorkommen dieser Spaltenanzahl in der Datei sind. Am Ende gehen wir einfach das Array durch und drucken. Wenn wir das Obige auf Ihr Beispiel anwenden, ergibt sich:

$ awk '{ nums[NF]++}END{for(num in nums){printf "%d columns: %d\n", num, nums[num]}}' file
1 columns: 7
2 columns: 14
3 columns: 3

Ein (kleiner) Nachteil dieses Ansatzes ist, dass Sie für jede Zeile der Datei einen Eintrag im Speicher behalten müssen. Das ist kein Problem, es sei denn, Ihre Datei ist absolut riesig oder Sie haben extrem wenig Speicher zur Verfügung. Wenn das aber der Fall ist, können Sie es umgehen, indem Sie einfach die Anzahl der Felder pro Zeile ausdrucken und dann zählen:

$ awk '{ print NF}' file | sort | uniq -c
      7 1
     14 2
      3 3

Oder um die gleiche Ausgabe zu erhalten:

$ awk '{ print NF}' file | sort | uniq -c | while read num fields; do printf "%d columns: %d\n" "$num" "$fields"; done
7 columns: 1
14 columns: 2
3 columns: 3

Antwort2

Eine Nicht- awkLösung, vielleicht etwas umständlich:

$ a=$(grep '^[GHTER_0-9]\+[[:space:]]\+[GHTER_0-9]\+[[:space:]]\+[GHTER_0-9]\+$' file | wc -l)
$ b=$(grep '^[GHTER_0-9]\+[[:space:]]\+[GHTER_0-9]\+$' file | wc -l)
$ c=$(grep '^[GHTER_0-9]\+$' file | wc -l)
$ printf "3 columns %s\n2 columns %s\n1 column %s\n" $a $b $c
3 columns 3
2 columns 14
1 columns 7

verwandte Informationen