Ich habe eine Datei, die so aussieht:
1
2 4 5 6 7 19
20
22
24 26 27
29 30 31 32 34 40 50 56 58
234 235 270 500
1234 1235 1236 1237
2300
in Anbetracht dessen, dass meine echte Datendatei riesig ist. Ich möchte also prüfen, was die maximale Anzahl in dieser Datendatei ist. Außerdem möchte ich im Durchschnitt prüfen, wie viele Spalten in Zeilen vorhanden sind. In diesem kleinen Beispiel beispielsweise beträgt die maximale Spaltenanzahl 9 (in der 5. Zeile) und im Durchschnitt gibt es 3,33 Spalten in Zeilen. Irgendwelche Vorschläge, bitte?
Antwort1
$ awk 'NF > m { m = NF } { s += NF } END { printf("Max = %d\nAvg = %g\n", m, s/NR) }' data.in
Max = 9
Avg = 3.33333
Das awk
Skript verfolgt die maximale Anzahl von Feldern (Spalten) in m
und die Summe der Anzahl der Felder in s
. Wenn das Ende des Eingabestroms erreicht ist, gibt es die gesammelten Statistiken aus.
Die Anzahl der Felder im aktuellen Datensatz (Zeile) beträgt NF
, und die Anzahl der bisher gelesenen Datensätze beträgt NR
.
Die folgende Version verfolgt auch den Datensatz mit der größten Anzahl von Feldern:
awk 'NF > m { m = NF; r = NR } { s += NF } END { printf("Max = %d (%d)\nAvg = %g\n", m, r, s/NR) }' data.in
Max = 9 (6)
Avg = 3.33333
Antwort2
Sie können das Dienstprogramm „dc“ für mathematische Aufgaben verwenden:
dc -e "
[zsmlksn]sb
[lk1+skzls+ss]sa
[[Max = ]nlmn[(]nlnn[)]n10an[Avg = ]n5klslk/1/n10an]sp
[lpxq]sq
[?z0=qlaxzlm<bcl?x]s?
0ddddsksmsnssd=?
"
Was unten gezeigt wurde, in Bezug auf die Funktionsweise des oben genannten
tr '\t-' ' _' data.in | # dc wants negative numbers to begin with underscores
dc -e "
[
z sm # store current num of cols in register "m"
lk sn # store row num in register "n"
]sb
[
lk 1 + sk # increment the number of rows
z ls + ss # add num of cols to running sum of cols
]sa
[
[Max=]n
lmn # put max number of cols on ToS & print it
[(]n
lnn # put row num at which max number of cols are present on ToS & print it
[)]n
10an
[Avg=]n
5k ls lk /1/n # accuracy of 5 digits, compute average = sum of cols / total num of cols
10an
]sp
[
lpx # print the results by invoking the macro "p"
q # quit
]sq
# while loop for reading in lines
[
? z 0 =q # quit when no columns found in the current line read in
lax # macro "a" does: rows++, sum+=cols
z lm <b # update max cols value stored in register "lm" when cols > lm
c # clear out the line and read in the next line
l?x # read the next line
]s?
# initializations+set the ball rolling:
# register "sk" -> line kount
# register "sm" -> max cols
# register "sn" -> row number corresp. to max cols
# register "ss" -> sum of cols
0
d d d d
sk sm sn ss
d=?
"
Ergebnisse
Max = 9(6)
Avg = 3.33333