Was macht dieser grep- und sed-Befehl?

Was macht dieser grep- und sed-Befehl?

Ich weiß bereits, was einzelne Teile dieses Befehls bewirken:

zgrep -v "org" /path/to/files/* | zgrep "FollowEvent" | zgrep -o 'login":"[^"]*"' | cut -d'"' -f3 | sort | uniq -c | sed '1i{
       s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}' > usernames_followevents.txt

Stück für Stück:

1) zgrepwird zum grepDurchsuchen von .json.gzDateien verwendet

2) zgrep -v "org" /path/to/files/*bedeutet, in jeder Datei nach Einträgen zu suchen, /path/to/files/*die nicht enthalten "org".

3) |ist ein Pipe-Zeichen; es bedeutet „und dann“

4) zgrep "FollowEvent"bedeutet, die Zeichenfolge "FollowEvent"innerhalb der gefundenen Ergebnisse des ersten Zgrep zu finden.

5) |ist ein Pipe-Zeichen; es bedeutet „und dann“

6) zgrep -o 'login":"[^"]*"'bedeutet, dass nach nicht leeren Übereinstimmungen für die Zeichenfolge login":"und den gesamten Text gesucht wird, der im Eintrag auf das Wort „login“ folgt.

7) | cut -d'"' -f3bedeutet „und dann nur das dritte Feld aus der resultierenden Übereinstimmung nehmen“, was in diesem Fall ein Benutzername ist.

8) | sort | uniq -cbedeutet „und dann die Benutzernamen sortieren und dann die Anzahl der eindeutigen Vorkommen jedes Benutzernamens zählen“.

Bisher haben wir:

zgrep -v "org" /path/to/files/* | zgrep "FollowEvent" | zgrep -o 'login":"[^"]*"' | cut -d'"' -f3 | sort | uniq -c

Dabei werden in allen Einträgen in allen Dateien in /Pfad/zu/Dateien/*, die nicht die Zeichenfolge „org“, aber die Zeichenfolge „FollowEvent“ enthalten, alle Benutzernamen (das ist der Text im dritten Feld nach „Login“) gesucht und anschließend diese Benutzernamen sortiert und gezählt, wie oft jeder Benutzername vorkommt.

Mein Problem betrifft diesen Teil:

sed '1i{ s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/;$a}'

Soviel weiß ich (oder glaube zu wissen):

1) sedist ein Stream-Editor, der die Bearbeitung von Text ermöglicht.

2) sed '1i{bedeutet „in der vorhergehenden Zeile { einfügen“

3) Insgesamt gibt dieser Befehl {"username":count of that username}alle Benutzernamen in allen Dateien zurück, wie zuvor besprochen. Er legt diese dann in einer Datei namens ab usernames_followevents.txt.

4) Der Teil "\2":bedeutet „Setzen Sie doppelte Anführungszeichen um den Benutzernamen, der das zweite Feld ist (?), und fügen Sie dann ein : ein.“

Ich möchte den sedBefehl manipulieren, aber ohne die restlichen Details zu verstehen, kann ich keine Änderungen vornehmen.

Kann mir bitte jemand erklären, was die einzelnen Teile des sedBefehls bewirken?

Antwort1

Die Art und Weise, wie der sed-Befehl jetzt geschrieben ist, ist falsch. Es sollte entweder ein Skript wie dieses sein:

1i{
s/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/
$a}

oder in einer einzelnen Zeile wie dieser:

sed -e '1i{' -e 's/\s*\([0-9]*\)\s*\(.*\)/"\2": \1,/' -e '$a}'

Buchstäblich alles, was Sie nach Befehlen iund abis zu einem Zeilenumbruch oder Ende eines Ausdrucks (mit -e) einfügen, wird direkt auf der Standardausgabe gedruckt.

Was es bewirkt, wollen wir im Folgenden aufschlüsseln:

1i{

1ist eine Zeilenadresse. Sie teilt sed mit, wann ein Befehl ausgeführt werden soll. Wenn der Inhalt der ersten Zeile in den Musterbereich eingelesen wird (ohne den abschließenden Zeilenumbruch), ifügt es in der Standardausgabe in einer separaten Zeile '{' ein. Beachten Sie, dass der Musterbereich unverändert bleibt, das '{' wurde ihm nicht hinzugefügt.

sist der Such- und Ersetzungsbefehl, der vielseitigste Befehl in sed. \sentspricht einem Leerzeichen. \(regex\)gruppiert den regulären Ausdruck darin wie in der Mathematik, speichert aber auch, was damit übereinstimmt, in einem numerischen Register basierend auf der Reihenfolge dieser Gruppe: \1 bis \9.

Die Ausgabe uniq -csieht ungefähr so ​​aus:

    occurrences string
    3 user

Jetzt der komplizierte Teil:

\s*\([0-9]*\)\s*\(.*\)

Immer noch in Zeile 1. Der Musterraum besteht aus einer Reihe von Leerzeichen, dann „3 Benutzer“. Um dies zu finden, suchen wir null oder mehrmals nach Leerzeichen, dann viele Male nach einer Ziffer, also einer Zahl (meiner Meinung nach hätte es + statt * sein sollen), die im Register \1 gespeichert ist, dann nach einem Leerzeichen (* ist meiner Meinung nach nicht erforderlich), dann viele Male nach einem beliebigen Zeichen (auch hier wäre + besser gewesen), das im Register \2 gespeichert ist. Das Vorkommen befindet sich jetzt also in \1 und String/Benutzer in \2.

"\2": \1,

Die ganze Zeile wurde abgeglichen und Teile wurden gespeichert. Jetzt ersetzen wir das, was abgeglichen wurde, durch ein Anführungszeichen, dann durch den Benutzer, dann durch ein Anführungszeichen, einen Doppelpunkt, ein Leerzeichen, ein Vorkommen und ein Komma.

$a}

$ist ebenfalls eine Zeilenadresse. Wenn die aktuelle Zeile die letzte ist (im Moment nicht), rufen Sie den aBefehl auf, um '}' in einer separaten Zeile an die Standardausgabe anzuhängen.

Dies ist das Ende der Codeverarbeitung für diese Zeile, der Musterbereich wird automatisch so gedruckt, wie er nach Abschluss der Manipulation ist, dann wird der Inhalt der zweiten Zeile gelesen und der gesamte Zyklus wiederholt.

Beispielausgabe:

{
"user": 3,
}

Dies ist grundsätzlich ein JSON-Dateiformat, allerdings mit falscher Einrückung.

Das ist es. Entschuldigen Sie, dass ich Romane schreibe :)

verwandte Informationen