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 -F
Option 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 NF
fü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, nums
dessen 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- awk
Lö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