
Ich versuche, Daten zwischen zwei übereinstimmenden Mustern zu extrahieren, jedoch nur, wenn der Inhalt nicht leer ist. Dabei treten Probleme auf:
Hier ist ein Beispiel:
==============================
Queue Manager is : MQ73PCRTB2
==============================
==============================
Queue Manager is : MQ73PCSH01
==============================
_________________________________
Current instances are over 80% of max instnaces allowed for the channel WAS.P2QG2E00.SVRC
Max Instances allowed is 100
Current Instances running is 100
==============================
Queue Manager is : MQ73PCSH02
==============================
_________________________________
Current instances are over 80% of max instnaces allowed for the channel WAS.P2QG2E00.SVRC
Max Instances allowed is 100
Current Instances running is 100
==============================
Queue Manager is : MQ73PCSHA1
==============================
==============================
Queue Manager is : MQ73PCSHA2
==============================
In der Ausgabe möchte ich Folgendes sehen:
==============================
Queue Manager is : MQ73PCSH01
==============================
_________________________________
Current instances are over 80% of max instnaces allowed for the channel WAS.P2QG2E00.SVRC
Max Instances allowed is 100
Current Instances running is 100
==============================
Queue Manager is : MQ73PCSH02
==============================
_________________________________
Current instances are over 80% of max instnaces allowed for the channel WAS.P2QG2E00.SVRC
Max Instances allowed is 100
Current Instances running is 100
Ich weiß, dass ich Zeilen vor und nach dem übereinstimmenden Text extrahieren und alles zwischen übereinstimmenden Mustern extrahieren muss, möchte aber wissen, wie ich alles zwischen übereinstimmenden Mustern nur drucken kann, wenn die Daten nicht leer sind.
Folgendes habe ich versucht und es hat nicht funktioniert:
grep -zPo '(?s)Queue(?:.(?!</Queue))*?\Current*?</Queue'
Die ursprüngliche Textdatei wird von einem anderen Skript generiert.
Es könnten mehr als 3 Datenzeilen zwischen dem passenden Muster „Warteschlange“ vorhanden sein.
Antwort1
Du könntest es so versuchen
sed '/Queue/{N;$d;N;$d;N;/==$/d}' infile
Dies zieht nur die nächsten drei Zeilen ein, wenn die Zeile übereinstimmt Queue
. Wenn der Musterbereich mit einem Trennzeichen 1 endet , wird es gelöscht (oder wenn entweder 2 die 1. oder die 2. Zeile, die eingezogen wird, die letzte in der Eingabe ist).
Wenn andere Zeilen mit aufeinanderfolgenden =
Zeichen enden können, sollten Sie das ==$
im regulären Ausdruck durch eine genaue Übereinstimmung für das Trennzeichen ersetzen, z. B.=\{37\}$
1: Dies setzt voraus, dass ein Trennzeichen eine Zeilenübereinstimmung ist ^[[:blank:]]*==*$
(also keine Leerzeichen am Ende).
2: Da der Inhalt Ihrer Datei von einem Skript erzeugt wird, sollte die Datei immer mit einer leeren Zeile enden. Daher sollte sed nur prüfen, ob die zweite eingefügte Zeile die letzte Zeile in der Datei ist (um festzustellen, ob der letzte Block leer ist). In Ihrem Beispiel fehlt jedoch diese letzte Zeile, daher dieentweder...
Antwort2
BEGIN { RS="=====*\n" }
/Queue Manager/ {
manager = $0; next;
}
/[a-z]/ {
print RT manager RT $0;
}
Die erste Regel setzt das Datensatztrennzeichen auf vier oder mehr Gleichheitszeichen. Die zweite Regel verfolgt den „Header“, also den Datensatz, der die Zeichenfolge „Queue Manager“ enthält. Die dritte Regel druckt den Header und den aktuellen Datensatz, wenn der Datensatz mindestens einen Kleinbuchstaben enthält, also nicht leer ist.