Sed/Awk speichert Text zwischen Mustern, wenn er eine Zeichenfolge enthält

Sed/Awk speichert Text zwischen Mustern, wenn er eine Zeichenfolge enthält

Ich habe ein Problem mit E-Mails. Ich muss alle Nachrichten zwischen 2 Personen abrufen: [email protected]und [email protected].

Der file:

From: [email protected]
to: [email protected]
<body of the message1>

From: [email protected]
to: [email protected]
<body of the message1>

From: [email protected]
to: [email protected]
<body of the message1>

From: [email protected]
to: [email protected]
<body of the message1>

From: [email protected]
to: [email protected]
<body of the message1>

Ich habe versucht, Folgendes zu verwenden sed:

sed -n "/From: [Ss]omebody1/,/From: /p" inputfile > test.txt

Als Ergebnis habe ich alle E-Mails von someone1 zum test.txtAblegen erhalten.

Die Frage ist: Wie sollte die Struktur aussehen, sedum nur E-Mails zwischen jemand1 und einer Person zu erhalten?

Antwort1

Mit sed:

sed -n '/^From: [email protected]/{h;n;/^to: [email protected]/{H;g;p;:x;n;p;s/.//;tx}}' file

  • /^From: [email protected]/: Suche zuerst nach der From:E-Mail-Adresse
    • h;Speichern Sie diese Zeile im Haltebereich.
    • n;lade die nächste Zeile (die to:Zeile).
  • /^to: [email protected]/: Suche nach der to:E-Mail-Adresse
    • H;Hängen Sie diese Zeile an den Haltebereich an.
    • g;Kopiere den Haltebereich in den Musterbereich.
    • p;Drucken Sie den Musterbereich.
    • :x;Legen Sie ein Label mit dem Namen fest x.
    • n;lade die nächste Zeile (den E-Mail-Text)
    • p;Drucken Sie diese Zeile.
    • s/.//Nehmen Sie in dieser Zeile eine Ersetzung vor (ersetzen Sie nur ein Zeichen) …
    • tx... dass der tBefehl prüfen kann, ob die Ersetzung erfolgreich war (wenn die Zeile nicht leer ist, wie am Ende des E-Mail-Texts). Wenn ja, springen Sie zurück zum Label xund wiederholen Sie den Vorgang, bis eine leere Zeile erscheint. Wenn nicht, springen Sie zum Ende des Skripts.

Die Ausgabe:

From: [email protected]
to: [email protected]
<body of the message1>

From: [email protected]
to: [email protected]
<body of the message1>

Antwort2

Mit awk:

awk '/From: [Ss]omebody1/{flag=1;next} \
  /to\: person1/ {if (flag>0) {flag=2; print; next} else {flag=0; next}} \
 /From/{flag=0} {if (flag==2){print NR,flag, $0}} ' input.txt 
  • /From: [Ss]omebody1/{flag=1;next} \Setzen Sie bei Übereinstimmung eine Flag-Variable auf 1 und überspringen Sie die Zeile.
  • /to\: person1/ Wenn die Flagge 1 ist, aktualisieren Sie sie auf 2, andernfalls setzen Sie sie auf 0 zurück.
  • /From/{flag=0} Bei einer Übereinstimmung wird der Flag-Wert zurückgesetzt.
  • {if (flag==2){print NR, $0}}Wenn die Flagge 2 ist, wird dieZeilennummerund die Linie.

Ändern Sie den Wert, um person1unterschiedliche Übereinstimmungen zu erhalten.

Verwendete Eingabedatei

From: [email protected]
to: [email protected]
<body of the message1>

From: [email protected]
to: [email protected]
<body of the message2>

From: [email protected]
to: [email protected]
<body of the message3>

From: [email protected]
to: [email protected]
<body of the message4>

From: [email protected]
to: [email protected]
<body of the message5>

verwandte Informationen