Nur den ersten Treffer einmal drucken

Nur den ersten Treffer einmal drucken

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.2084839einmal 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;

exitim awk-Befehl wird nach dem Drucken der ersten Übereinstimmung beendet.

ODER

Leiten Sie die Ausgabe des forBefehls einfach an den folgenden awk-Befehl weiter.

for .... | awk -F'[(/]' '{print $2;exit}'

Antwort2

Sie benötigen die Schleife nicht for– ein einzelner Aufruf grepgibt 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 awknoch grepeines, 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.shund ihm einen String und einen Dateinamen als Argument geben. Diese werden dann zu $1bzw. $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 fornicht verwenden . ii) sehr falsch, da dadurch der Wert jedesifor i in ...iWortund 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 awkSie, dass sich das "$1"nicht in einfachen Anführungszeichen befindet. Dadurch erweitert Bash es auf den Inhalt, der aktuell in enthalten ist, $1bevor es an weitergegeben wird awk.

verwandte Informationen