Ich versuche, einige triviale Statistiken zu einigen Debug-Ausgaben zu erhalten.
Jede Debugzeile hat die Form(class name)(delimiter 1)(object ID)(delimiter 2)(method name)(delimiter 3)(log message)
Ich möchte wissen, wie viele Zeilen von welchen Methoden stammen.
Wenn jede Zeile auf reduziert werden kann (class name)(delimiter)(method name)
, möchte ich im Wesentlichen wissen, wie oft jede dieser Reduzierungen in der Protokolldatei vorkommt.
Welchen Befehl kann ich in Bash ausführen, um die Zählung durchzuführen?
(Ich mache das auf macOS mit Macports und ersetze die meisten standardmäßigen BSD-Tools durch GNU-Tools.)
Ich kann den Klassennamen mit extrahieren grep -o -E "^.*(delimiter 1)
oder den Methodennamen mit extrahieren grep -o -E "(delimiter 2).*(delimiter 3)"
oder beides mit hervorheben grep --color=always -E "^.*(delimiter 1)|(delimiter 2).*(delimiter 3)"
. Ich bin bei der Suche nach einer Möglichkeit, nur die beiden Übereinstimmungen auszugeben , die dann zum Zählen grep
durchlaufen werden können, nicht weitergekommen.| uniq -c
Gibt es eine Möglichkeit, grep
beide Übereinstimmungen für jede Zeile auszudrucken, anstatt nur eine Übereinstimmung oder die gesamte Zeile?
Antwort1
Im Wesentlichen kann dies erreicht werden durch
sed -r -n 's/(^.*)(delimiter 1)(.*)(delimiter 2)(.*)(delimiter 3)(.+$)/\1(delimiter)\5/p' <( command that generates debug logs ) | sort | uniq -c | sort -rn
(adaptiert vonHier)
.*
kann zu viele Übereinstimmungen ergeben;sed
ist gierig und möchte so viele Übereinstimmungen wie möglich so früh wie möglich erzielen, daher müssen dies z. B. Negierungen der Trennzeichen sein (was kompliziert sein kann, wenn Sie unpraktische Trennzeichen haben)- Der Übergang von „
^
bis“$
ist wichtig. Wenn Ihr Ausdruck nicht mit der gesamten Zeile übereinstimmt,sed
wird der nicht übereinstimmende Teil in die Ausgabe aufgenommen. - Klammern sind nur um den Klassennamen und den Methodennamen herum erforderlich. Das Entfernen der anderen Klammern bedeutet, dass die Zahlen am Ende geändert werden, da sich die Zahlen in der Reihenfolge auf eingeklammerte Teilausdrücke beziehen. (Wenn sie alle eingeschlossen werden, kann mehr von dem angezeigt werden, was in der
sed
Ausgabe passiert, z. B. indem das Ende in geändert wird/\1(delimiter)\5 -- \1\2\3\4\5\6\7/p
.) sort
muss vorher ausgeführt werden,uniq -c
dauniq -c
nur Läufe aufeinanderfolgender identischer Zeilen gezählt werden, nicht aufeinanderfolgende identische Zeilen werden separat gezähltuniq -c
kann nicht ersetzt werden durchsort -u
, weilsort -u
nur Duplikate gelöscht werden, sie werden nicht gezählt- Das Finale
sort
ist nicht notwendig, um die Frage wie gestellt zu beantworten - Ja, wenn Sie reguläre Ausdrücke zur Lösung eines Problems verwenden, haben Sie jetzt zwei Probleme.