GNU/Linux >> LINUX-Kenntnisse >  >> Linux

So analysieren Sie XML und Strip-Tags mithilfe von XPATH-Beispielen in Linux (So kombinieren Sie mehrere Befehle mit PIPE in Linux)

Dieses Tutorial erklärt den Prozess zum Erstellen nützlicher mehrteiliger Befehle Stück für Stück.

Um komplexe Befehle im Terminal zu erstellen, müssen wir die Rohrleitungen verstehen. Piping nimmt im Grunde die Ausgabe eines Befehls und sendet sie als Eingabe an einen anderen Befehl. Dies geschieht mit dem | (Rohr)-Symbol.

Letzten Monat musste ich bei einem kleinen Projekt wiederholt ähnliche XML-Dateien lesen, um Testdaten für ein anderes Programm bereitzustellen. Ich müsste es so häufig tun, dass es lästig wäre, es herunterzuladen, zu speichern, zu parsen und zu wiederholen. Die grundlegenden Anforderungen waren:

  1. XML von URL abrufen
  2. Parse das XML und wähle nur zwei Attribute aller Elemente aus
  3. Entfernen Sie die Tags, sodass nur der Inhalt übrig bleibt
  4. Zur Standardausgabe senden

1. Beweisen Sie, dass die Befehlszeile XML parsen kann

Ich hatte letztes Jahr die Ruby-Bibliothek REXML::Xpath für ein Skript verwendet und erinnerte mich, dass es eine Perl-Version auf der Kommandozeile gab. Sie können es mit CPAN installieren:

$ cpan XML::XPath

Lassen Sie uns eine beispielhafte Mitarbeiterdatei verwenden, um mit der Idee zu spielen. Öffnen Sie diese employee.xml-Datei in einem Browser, öffnen Sie diese in einem Browser und speichern Sie sie unter employee.xml.

Jetzt haben wir unseren xpath-Befehl und eine Datei zum Spielen.

Testen Sie es mit einem einfachen Pfad:

$ xpath employees.xml '/DIRECTORY/EMPLOYEE/FIRST_NAME'
­­ NODE ­­
<FIRST_NAME>Steven</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Susan</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Marigold</FIRST_NAME>­­ NODE ­­
...
<FIRST_NAME>Sunny</FIRST_NAME>­­ NODE ­­
<FIRST_NAME>Flo</FIRST_NAME>

Exzellent! Es druckt das FIRST_NAME-Attribut jedes /EMPLOYEE auf dem ausgewählten Pfad. Aber wie wählen wir mehrere XPath-Elemente aus? Wenn wir uns die XPath-Syntax ansehen, sehen wir einen Weg. Kombinieren der XPath-Ausdrücke mit dem | Zeichen, erstellen wir einen ODER-Ausdruck.

$ xpath employees.xml '/DIRECTORY/EMPLOYEE/ FIRST_NAME | /DIRECTORY/EMPLOYEE/LAST_NAME'
--­­ NODE ­­--
<FIRST_NAME>Steven</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Sanguini</LAST_NAME>­--­ NODE ­--­
<FIRST_NAME>Susan</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Aquilegia</LAST_NAME>--­­ NODE --­­
...
<FIRST_NAME>Flo</FIRST_NAME>­­-- NODE ­­--
<LAST_NAME>Lobalessia</LAST_NAME>

Beachten Sie, hier | wird als ODER-Operator interpretiert und nicht als Ausgabeumleitung.

Außerdem wählen wir in dieser Anweisung sowohl X als auch Y aus. Warum wählt OR beide aus? Es wertet jeden Knoten im XML-Dokument separat aus, und wenn der Knoten entweder A oder B ist, besteht er die Bewertung und wird an die Ausgabe übergeben.

2. XML herunterladen und an STDOUT senden

Dieser nächste Schritt wird tatsächlich früher auf der Befehlszeile kommen und wir werden ihn separat erstellen. Ich ziehe es vor, die schwierigsten oder „das geht nicht“-Befehlseinträge zuerst als Proof of Concept zu erstellen. Es wäre sinnlos, die umgebende Befehlszeilenarbeit zu erledigen, wenn der erste Schritt nicht funktionieren kann.

cURL ist ein leistungsstarker Befehl für HTTP-Interaktionen. Diese Curl-Beispiele bringen Sie in die richtige Richtung.

Wir geben einen Standort an und folgen bei Bedarf Weiterleitungen. Verwenden Sie dazu diese Option:-L ‘https://www.thegeekstuff.com/scripts/employees.xml’

Wir schalten die Informationsausgabe von cURL ab. Und geben Sie das GET-Protokoll an. Verwenden Sie dazu diese Option:-s G

Lassen Sie uns also unseren Befehl auf der URL für die zuvor heruntergeladene Datei testen:

$ curl -­s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml'
<?xml version="1.0" encoding="UTF­8"?>
<DIRECTORY>
<EMPLOYEE>
<FIRST_NAME>Steven</FIRST_NAME>
<LAST_NAME>Sanguini</LAST_NAME>
<STORE_NUMBER>4</STORE_NUMBER>
<SHIFT>FIRST</SHIFT>
<AUM>$2.44</AUM>
<ID>031599</ID>
</EMPLOYEE>
..

Es ist standardmäßig STDOUT. Was gut ist, da wir es jetzt zu XPath umleiten und das Dateiargument entfernen:

$ curl ­-s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml' | xpath \
'/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID'
­--­ NODE ­­--
<LAST_NAME>Sanguini</LAST_NAME>­­-- NODE ­­--
<ID>031599</ID>­­ NODE ­­
<LAST_NAME>Aquilegia</LAST_NAME>­­-- NODE -- ­­
<ID>030699</ID>­­-- NODE ­­--
...
<LAST_NAME>Lobalessia</LAST_NAME>--­­ NODE --­­
<ID>022299</ID>

Dies erzeugt die erwartete Ausgabe. Groß! Nicht sicher warum, aber XPath sendet „NODE“ an den Standardfehler (STDERR). Aber wir werden später einen möglichen Grund sehen.

3. XML-Tags entfernen

Jetzt müssen wir in der Lage sein, diese Tags zu entfernen und nur den Inhalt zu erhalten. Sed ist das beste Werkzeug, um spontan reguläre Ausdrücke zu ersetzen. Das Erlernen von REGEX würde den Rahmen dieses Artikels sprengen.

Weitere Informationen finden Sie in unserer Artikelserie zu regulären Python-Ausdrücken.

Wenn ich komplizierte Befehle mit mehreren Argumenten und Flags mache, finde ich es am besten, mit einem einfachen Beispiel zu arbeiten, bis ich es genau richtig verstehe, und es dann in den Kontext mit den echten Argumenten einzufügen. Wir leiten eine einfache Zeichenfolge für eine Testsubstitution an sed weiter. Sed arbeitet standardmäßig mit STDIN.

$ echo "This<strong> is </strong>a test." | sed ­-re 's/i//g'
Ths<strong> s </strong>a test.

OK. Das funktioniert. Schreiben Sie jetzt die Suche um, um ein Tag zu ersetzen.

$ echo "This<strong> is </strong>a test." | sed ­-re 's/<\w+>//g'
This is </strong>a test.

Gut. Lassen Sie uns das Schließen-Tag entfernen, indem wir „/“ hinzufügen, das durch das Präfix „\“ maskiert und durch das Suffix „?“ optional gemacht wird

$ echo "This<strong> is </strong>a test." | sed ­re 's/<\/?\w+>//g'
This is a test.

Perfekt. Genau das, was wir erwartet haben.

4. Alles zusammenfügen

Nachdem wir nun die einzelnen Teile unseres Befehls erstellt haben, fügen wir sie in logischer Reihenfolge zusammen, verbunden durch | .

curl ­-s -­G -­L ' https://www.thegeekstuff.com/scripts/employees.xml' | \
xpath '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID ' | \
sed ­-re 's/<\/?\w+>//g'

Ausgabe:

Found 72 nodes:
--­­ NODE -- ­­
­--­ NODE ­­--
...
Sanguini031599Aquilegia030699...

Oh oh! Vielleicht sind deshalb die Markierungen „ NODE “ dort. Wenn wir dies an eine Datei weiterleiten, folgt der NODE-Text nicht. Sie werden an den Standardfehler (STDERR) gesendet, aber wir können auf STDOUT umleiten, indem wir `2>&1` (Erklärung) verwenden und den sed-Ersatz `sed re 's/ NODE //g'` verwenden, um auf die gleiche Weise wie die zu entfernen Tags.

curl -­s -­G -­L 'https://www.thegeekstuff.com/scripts/employees.xml' | \
xpath '/DIRECTORY/EMPLOYEE/LAST_NAME | /DIRECTORY/EMPLOYEE/ID '
2>&1| sed -­re 's/­--­NODE--­­//g' | sed -­re 's/<\/?\w+>//g'

Ausgabe:

Found 72 nodes:
Sanguini
031599
Aquilegia
030699
...
Lobalessia
022299

Perfekt. Wenn ich jetzt an meinem Projekt arbeite, kann ich schnell Beispieldaten aus XML-Dateien im Internet nach STDOUT übertragen, ohne dass ich Dateien speichern oder komplizierte Software ausführen muss. Wir können dies sogar an `tail –n+3` leiten, um diese ersten beiden Antwortzeilen abzuschneiden.

Dieser Artikel ist nur ein Beispiel für verschiedene Dinge, die Sie tun können, wenn Sie lernen, wie Sie mehrere Befehle mit Pipe kombinieren.


Linux
  1. Linux-Befehle – Übersicht und Beispiele

  2. Überprüfen Sie den Speicherplatz in Linux mit den Befehlen df und du

  3. Head- und Tail-Befehle in Linux mit Beispielen erklärt

  4. Verwendung von Pipes und Named Pipes unter Linux (mit Beispielen)

  5. So legen Sie die Linux-Prozesspriorität mit den Befehlen nice und renice fest

So führen Sie Befehle von der Standardeingabe mit Tee und Xargs in Linux aus

So zeigen Sie Cheatsheets für Linux-Befehle mit z

So verwenden Sie die Befehle Pbcopy und Pbpaste unter Linux

So sichern Sie Dateien und Verzeichnisse mit Rsync unter Linux

So führen Sie Linux-Apps unter Windows 10 und 11 mit WSL aus

So führen Sie mehrere Linux-Befehle in einem einzigen Befehl aus