Gibt einen bestimmten übereinstimmenden (Unter-) Wert mit grep in Linux zurück

426
Robin Gould

Ich betreibe einen Zabbix-Agenten (Protokollierungssoftware) auf Ubuntu und möchte einen internen IPIP / GRE-Tunnel anpingen, um die Qualität der Verbindung ständig zu messen.

Jetzt erlaubt ein Zabbix-Agent standardmäßig nicht, dass ein Ping-Befehl für einen internen Tunnel ausgeführt wird. Glücklicherweise können jedoch "Benutzerparameter" erstellt werden. Grundsätzlich können Sie einen einzigen Unix-Shell-Befehl ausführen und die Daten Ihrer Software zuführen.

Dazu muss ich einen fping / ping-Befehl ausführen, der einen einzelnen Wert für zabbix abruft. Ich möchte, dass dieser Wert die Anzahl der Dezimalsekunden oder Millisekunden der Latenzzeit oder 0 bei keiner Verbindung für alles über 1 Sekunde ist. Unten habe ich bereits einen Befehl ausgearbeitet, der 5 Pings an die Tunnel-IP ausführt und die Durchschnittswerte zurückgibt.

(die IP-Adresse unten ist ein Beispiel) Dies ist, was ich bisher bekommen habe:

fping -e -q -p 1000 -c 5 8.8.4.4 2> /dev/null | grep -oP '[0-9\.]+/([0-9\.]+)/[0-9\.]+$' 

Der vollständige Return-String sieht folgendermaßen aus:

8.8.4.4 : xmt/rcv/%loss = 5/5/0%, min/avg/max = 2.78/2.94/3.19" 

Nun ist das Ergebnis von grep:

2.78/2.94/3.19 

Ich möchte den zweiten Wert (2.94 oben) konsistent erhalten. Meine Frage lautet dann: Was ist der effektivste Weg, dies in einem einzigen Befehl zu tun?

0

2 Antworten auf die Frage

1
AFH

Ich würde sedstattdessen verwenden grep, also wird Ihr Filter zu:

... | sed -n 's%^.* = .* = .*/\(.*\)/.*%\1%pg' 

Anmerkungen:-

  • Da wir mit dem /Zeichen übereinstimmen, habe ich das normale Zeichenfolgenbegrenzungszeichen ersetzt %, um den Ausdruck zu vereinfachen, indem ich die Notwendigkeit eines Fluchtens vermeide /.
  • Wir passen die gesamte Zeile an und ersetzen sie durch das, was zwischen zwei Schrägstrichen nach zwei Gleichheitszeichen steht, die durch \(und \)in der Übereinstimmungszeichenfolge und \1in der Ersetzung begrenzt werden.
  • Wir geben nichts aus ( -n) außer in Zeilen, in denen Übereinstimmungen ( %pg) vorhanden sind.

Zur Vereinfachung meiner Darstellung habe ich .*die Zahlen verwendet. Sie können verwenden [0-9\.]+, aber Sie müssen Extended RE mit verwendengrep -rn ...

Wenn Sie es noch nicht verwendet sedhaben, empfehle ich dieses Tutorial .

Vielen Dank für Ihre Antwort. Wenn Sie jedoch den folgenden Befehl ausführen, erhalte ich ein leeres Ergebnis: fping -e -q -p 1000 -c 5 8.8.4.4 | sed -n 's% ^. * =. * =. * / \ (. * \) /.*% \ 1% pg' Wenn ich den Befehl jedoch manuell ausführe und das Ergebnis in ein Echo kopiere, funktioniert es. Was mache ich falsch ? Robin Gould vor 8 Jahren 0
anscheinend fping immer Ausgaben in stderr anstelle von stdin. Ich habe dies behoben, indem ich 2> & 1 am Ende des Befehls fping einfügte Robin Gould vor 8 Jahren 0
In `bash` können Sie die Weiterleitung auf` fping ... | & sed ... `verkürzen. AFH vor 8 Jahren 0
0
Richlv

Warum nicht cut -d/ -f8? Wie in:

echo '8.8.4.4 : xmt/rcv/%loss = 5/5/0%, min/avg/max = 2.78/2.94/3.19"' | cut -d/ -f8 
Das hat auch funktioniert, die sed-Lösung scheint jedoch flexibler zu sein :) Danke trotzdem! Robin Gould vor 8 Jahren 0
Dies ist eine gute Lösung, sofern in der Ausgabe von "fping" keine zusätzlichen Zeilen in unterschiedlichen Formaten vorhanden sind: Jede zusätzliche Zeile in der Eingabe von "cut" führt zu einer leeren Zeile in der Ausgabe. Um diese zu beseitigen, benötigen Sie einen zusätzlichen Filter `... | grep -v '^ $' `. AFH vor 8 Jahren 0
Natürlich hätte "sed" oder "awk" funktioniert - ich habe versucht, die einfachste Antwort auf das angegebene Problem zu geben :) Richlv vor 8 Jahren 0