Wie kann ich sed\awk verwenden, um nach bestimmten Zeilen in einer Datei zu suchen und dann alle nachfolgenden Zeilen abzugleichen, die einem anderen Muster entsprechen?

Wie kann ich sed\awk verwenden, um nach bestimmten Zeilen in einer Datei zu suchen und dann alle nachfolgenden Zeilen abzugleichen, die einem anderen Muster entsprechen?

Ich habe ein ähnliches Thema gefunden, konnte aber nicht herausfinden, wie ich es für meinen eigenen Gebrauch implementieren kann:

mehrere Zeilen nach einer passenden Zielzeile erfassen

Hier ist das Problem:

Ich versuche, es in einem eigenen Projekt zu implementieren, aber es scheint nicht zu funktionieren. Ich verwende Linux. Kann es jemand erklären?

Im Grunde versuche ich, ein Protokollbündel durchzugehen und bestimmte Zeilen zusammen mit ihrem Stapel/Details zu erfassen. Hier ist ein Beispiel:

2020-01-20T05:58:19.119Z verbose vpxa[6E21B70] [Originator@6876 sub=PropertyProvider opID=k5cokp1a-928316-auto-jwal-h5:70047736-92-01-84] [CommitChangesAndNotify] Updating cached values
2020-01-20T05:58:19.119Z info vpxa[6E21B70] [Originator@6876 sub=Default opID=k5cokp1a-928316-auto-jwal-h5:70047736-92-01-84] [VpxLRO] -- ERROR task-107599 -- **vm-1178** -- vim.VirtualMachine.reconfigure: vmodl.fault.InvalidArgument:
--> Result:
--> (vmodl.fault.InvalidArgument) {
-->    faultCause = (vmodl.MethodFault) null,
-->    faultMessage = (vmodl.LocalizableMessage) [
-->       (vmodl.LocalizableMessage) {
-->          key = "msg.disk.extendFailure",
-->          arg = (vmodl.KeyAnyValue) [
-->             (vmodl.KeyAnyValue) {

Ich möchte jede Zeile erfassen, die „vm-1178“ enthält, und alle nachfolgenden Zeilen, die mit „-->“ beginnen, bis sich das Muster ändert. Dann möchte ich mit der Suche nach vm-1178 beginnen, bis dies das nächste Mal auftritt usw.

Hoffe, das ergibt Sinn. Danke!

Antwort1

Versuche dies,

awk '!/^-->/{p=0} /vm-1178/{p=1} p'
  • !/^-->/{p=0}: Setzen Sie var p(wie print) auf 0, wenn die Zeile nicht mit beginnt -->.
  • /vm-1178/{p=1}: Setzen Sie var p= 1, wenn die Zeile übereinstimmt /vm-1178/.
  • p: Drucken Sie die Zeile, wenn pwahr ist (hier = 1).

Antwort2

Sie könnten awkzu diesem Zweck verwenden:

awk 'index($0,"vm-1178")>0 {in_pat=1; print; next} \
in_pat == 1 && $0 ~ /^-->/ {print; next} \
{in_pat=0}' logfile.txt

Es enthält drei Regeln:

  • Die erste Regel sucht nach Zeilen, die das Muster enthalten, druckt diese aus und setzt ein internes Flag in_patauf 1.
  • Die zweite Regel besagt, dass alle nachfolgenden Zeilen, die mit beginnen, -->ebenfalls gedruckt werden.
  • Die dritte Regel wird verwendet, um dieses Flag in der allerersten Zeile zurückzusetzennichtdas Muster enthalten oder nicht mit einem beginnen -->, sodass nichts gedruckt wird, bis das Muster erneut gefunden wird.

Beachten Sie, dass in der ersten Regel die indexFunktion anstelle einer RegExp-Übereinstimmung verwendet wird. Auf diese Weise können Sie auch nach Mustern suchen, die Zeichen enthalten, die in regulären Ausdrücken eine besondere Bedeutung haben.

Antwort3

Mit Perl würde dies funktionieren:

 perl -ne ' { $t=0 if ( !/^-->/ ); $t=1 if(/vm-1178/); print if($t); }' <filename>

verwandte Informationen