it-swarm.com.de

Inhalt aus einer Datei zwischen zwei Übereinstimmungsmustern extrahieren (nur HTML aus einer Datei extrahieren)

Ich habe eine Datei, die verschiedene Textformate enthält. Mein Ziel ist es, nur den HTML-Teil zu extrahieren und eine Datei mit diesem HTML-Code zu erstellen. Ich denke, dass es mit grep oder awk möglich ist. Meine Datei enthält auch folgende Zeilen:

Sender name `<[email protected]>`

Ich habe dieses Skript cat file1.html | grep -E "<[^>]*>" geschrieben. Das Problem ist aber, dass es auch die Zeilen als Sender name usw. ausgibt. Ich möchte den Inhalt erst nach dem Tag <html> extrahieren. Das ist also nicht nützlich für mich:

Return-Path: <[email protected]>
    for <[email protected]> (single-drop); Thu, 21 Sep 2017 18:34:07 +0400 (+04)
Return-path: <[email protected]>
    (envelope-from <[email protected]>)
References: <[email protected]>
From: test user <[email protected]>
X-Forwarded-Message-Id: <[email protected]>
Message-ID: <[email protected]>
In-Reply-To: <[email protected]>
2
DaviD

Dieses Ziel können wir mit dem Tool sed - Stream-Editor zum Filtern und Transformieren von Text erreichen. Die kurze Antwort finden Sie unter Punkt 5 . Aber ich habe beschlossen, eine detaillierte Erklärung zu schreiben.

0. Zuerst erstellen wir eine einfache Datei, um unsere Befehle zu testen:

$ printf '\nTop text\nSender <[email protected]>\n\n<html>\n\tThe inner text 1\n</html>\n\nMiddle text\n\n<HTML>\n\tThe inner text 2\n</HTML>\n\nBottom text\n' | tee example.file

Top text
Sender <[email protected]>

<html>
        The inner text 1
</html>

Middle text

<HTML>
        The inner text 2
</HTML>

Bottom text

1. Wir können alles zwischen den Tags <html> und </html> zuschneiden, einschließlich der folgenden:

$ sed -n -e '/<html>/,/<\/html>/p' example.file

<html>
        The inner text 1
</html>
  • Die Option -e script (--expression=script) fügt den auszuführenden Befehlen ein Skript hinzu. In diesem Fall lautet das hinzugefügte Skript '/<html>/,/<\/html>/p'. Obwohl wir nur ein Skript haben, können wir diese Option weglassen.

  • Die Option -n (--quiet, --silent) unterdrückt das automatische Drucken des Musterbereichs, und zusammen mit dieser Option sollten wir einige zusätzliche Befehle verwenden, um sed mitzuteilen, was gedruckt werden soll.

  • Dieser zusätzliche Befehl ist der Druckbefehl p, der am Ende des Skripts hinzugefügt wird. Wenn sed nicht mit der Option -n gestartet wurde, dupliziert der Befehl p die Eingabe.

  • Schließlich können wir durch die zwei durch Kommas getrennten Muster - /<html>/,/<\/html>/ - einen Bereich angeben. Bitte beachten Sie, dass wir \ verwenden, um das Sonderzeichen / zu umgehen, das hier die Rolle des Begrenzers spielt.

2. Wenn wir alles zwischen den Tags <html> und </html> zuschneiden möchten, ohne sie zu drucken, sollten wir einige zusätzliche hinzufügen Befehle:

$ sed -n '/<html>/,/<\/html>/{ /html>/d; p }' example.file

        The inner text 1
  • Die geschweiften Klammern { und } werden zum Gruppieren der Befehle verwendet.

  • Der Befehl d löscht jede Zeile, die dem Ausdruck html> entspricht.

3. Aber unser example.file hat auch <HTML> Tags in Großbuchstaben. Daher sollten wir die Groß- und Kleinschreibung der Musterübereinstimmung ignorieren. Wir könnten dazu das Flag /I zu den regulären Ausdrücken hinzufügen:

$ sed -n '/<html>/I,/<\/html>/I{ /html>/Id; p }' example.file

        The inner text 1
        The inner text 2
  • Der Modifikator I für den Abgleich mit regulären Ausdrücken ist eine GNU -Erweiterung, die bewirkt, dass bei REGEXP zwischen Groß- und Kleinschreibung unterschieden wird.

4. Wenn wir alle HTML-Tags zwischen den <html> -Tags entfernen möchten, können wir einen zusätzlichen Befehl hinzufügen, der analysiert und 'löscht'. Die Zeichenketten, die mit < beginnen und mit > enden:

sed -n '/<html>/I,/<\/html>/I{ /html>/Id; s/<[^>]*>//g; p }' example.file
  • Mit dem Befehl s werden die Zeichenfolgen, die mach für den Ausdruck /<[^>]*>/ verwendet, durch eine leere Zeichenfolge // - s/<old>/<new>/ ersetzt.

  • Das Muster-Flag g wendet die Ersetzung auf alle Übereinstimmungen mit dem regulären Ausdruck an, nicht nur auf die erste.

Wahrscheinlich möchten wir in diesem Fall den Befehl delete weglassen:

sed -n '/<html>/I,/<\/html>/I{ s/<[^>]*>//g; p }' example.file

5. Um die Änderungen an der Stelle der Datei vorzunehmen und eine Sicherungskopie zu erstellen, können wir die Option -i verwenden, oder wir können erstellen eine neue Datei basierend auf der Ausgabe von sed, indem > die Ausgabe in die neue Datei umgeleitet wird:

sed -n '/<html>/I,/<\/html>/I p' example.file -i.bak
sed -n '/<html>/I,/<\/html>/I p' example.file > new.file

Verweise:

6
pa4080