Ich habe einen Codeausschnitt, den ich verwende, um eine Protokolldatei zu analysieren und die benötigten Informationen auszudrucken.
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/ {print $7}'
done;
Das Problem besteht darin, dass die Antwort mehrmals angezeigt wird, wenn ich eine Eingabe mache:
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.284.3.17454802.933.1401109176.280.1)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.284.3.17454802.933.1401109176.283.1)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109696.2)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109706.51)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109758.100)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109773.149)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109810.198)
(1.3.51.0.1.1.10.10.30.48.2084865.2084839/1.2.840.113619.2.80.977011700.14346.1401109818.247)
Gibt es eine Möglichkeit, dies so zu kürzen, dass ich nur die erste Datenreihe einmal anzeigen muss? Ich muss nur 1.3.51.0.1.1.10.10.30.48.2084865.2084839
einmal ausdrucken.
Ich habe auch versucht, es folgendermaßen zu ändern, aber Bash gefällt das nicht:
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/' |
awk -F'[(/]' ' {print $2, exit}'
done;
Dann habe ich Folgendes versucht:
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk -F'[(/]' '/\([a-zA-Z0-9.]+/ {print $2, exit }'
done;
Antwort1
Versuche dies,
for i in $(cat ~/jlog/"$2"); do
grep "$1" ~/jlog/"$2" |
awk '/\([a-zA-Z0-9.]+/ {print $7; exit}'
done;
exit
im awk-Befehl wird nach dem Drucken der ersten Übereinstimmung beendet.
ODER
Leiten Sie die Ausgabe des for
Befehls einfach an den folgenden awk-Befehl weiter.
for .... | awk -F'[(/]' '{print $2;exit}'
Antwort2
Sie benötigen die Schleife nicht for
– ein einzelner Aufruf grep
gibt alle übereinstimmenden Zeilen aus der Datei aus, sodass Sie denselben Vorgang einfach so oft wiederholen, wie die Datei Zeilen enthält.
Technisch gesehen brauchen Sie weder beides awk
noch grep
eines, da beide Textübereinstimmungen durchführen können. Wenn Sie eine spezifischere Antwort wünschen, posten Sie einen Auszug der Protokolldatei und ein Beispiel für die gewünschte Ausgabe.
Antwort3
Sie haben nicht erklärt, was Sie eigentlich tun, also mache ich ein paar Annahmen. Ich gehe davon aus, dass Sie ein Skript namens ausführen foo.sh
und ihm einen String und einen Dateinamen als Argument geben. Diese werden dann zu $1
bzw. $2
. Vermutlich führen Sie es mit etwas Ähnlichem aus wie
foo.sh SearchPattern LogFileName
In jedem Fall ist die Schleife i) völlig nutzlos, da Sie die von der Schleife erstellte Variable for
nicht verwenden . ii) sehr falsch, da dadurch der Wert jedesi
for i in ...
i
Wortund nicht die ganze Zeile, was Sie wahrscheinlich gedacht haben: iii) die Ursache all Ihrer Probleme. Sie erhalten dieselben Ergebnisse mehrmals, weil Sie genau denselben Befehl mehrmals ausführen. Sie erhalten ein Ergebnis für jede Zeile Ihrer Datei.
Wie dem auch sei, was Sie wollen, kann mit etwas so Einfachem erreicht werden wie
grep "$1" ~/jlog/"$2" | awk '/\([a-zA-Z0-9.]+/ {print $7}'
Oder einfacher:
awk '/'"$1"'/\([a-zA-Z0-9.]+/ {print $7}' ~/jlog/"$2"
Beachten awk
Sie, dass sich das "$1"
nicht in einfachen Anführungszeichen befindet. Dadurch erweitert Bash es auf den Inhalt, der aktuell in enthalten ist, $1
bevor es an weitergegeben wird awk
.