Eine alte Weisheit besagt folgendes:
Wenn man erstmal einen Hammer in der Hand hat sieht alles aus wie ein Nagel.
Wenn man also halbwegs mit dem gängigen Unix-Werkzeugkasten (grep, cut, sed und awk) umgehen kann ist man geneigt diese Tools immer einzusetzen wenn Informationen aus Dateien zu extrahieren sind. Damit auf strukturierte Daten loszugehen ist allerdings nicht nur fehlerträchtig sondern auch alles andere als elegant.
Vor längerer Zeit habe ich hier mal auf jq hingewiesen. Das ist die Lösung wenn man in seiner Eigenschaft als Shell-Skript Daten aus JSON-Datensätzen braucht, mittlerweile konnte ich da schon einige Male drauf zurück greifen.
Jetzt habe ich was vergleichbares für XML-Daten gesucht, und wie es aussieht ist XMLStarlet das Werkzeug der Wahl (Disclaimer: ich habe nicht lange gesucht, NOCH bin ich für Gegenvorschläge offen ).
Erste Anwendung ist wieder, einen ungetrübten Blick auf das gewählte Dokument zu werfen. Mein Feed ist ein insofern ein schlechtes Beispiel als dass der Code ziemlich sauber formatiert ist, aber der Trick wird klar (die Sache mit dem Backslash am Zeilenende setze ich mal voraus):
1 2 |
wget -qO - http://www.schatenseite.de/feed/ | \ xmlstarlet fo |
Als nächstes interessieren mich vielleicht die Titel der letzten Artikel. Dazu selektiere ich alles was auf den XPath //rss/channel/item
matched, und lasse mir jeweils den Wert von title
ausgeben. Gefolgt von einem Zeilenumbruch:
1 2 |
wget -qO - http://www.schatenseite.de/feed/ | \ xmlstarlet sel -t -m '//rss/channel/item' -v title -n |
Aber wann habe ich denn meinen letzten Artikel veröffentlicht? Dazu matche ich nur auf das erste Element und lasse mir davon das pubDate
geben, zur besseren Lesbarkeit wieder gefolgt von einem Zeilenumbruch:
1 2 |
wget -qO - http://www.schatenseite.de/feed/ | \ xmlstarlet sel -t -m '//rss/channel/item[1]' -v pubDate -n |
Abschließend wüsste ich gerne noch worum es in meinem letzten Artikel ging. Auch das können wir formschön aus dem Feed extrahieren, allerdings wird das Kommando natürlich entsprechend unübersichtlicher. Wir matchen wieder auf das erste Item, lassen uns den Titel und einen Zeilenumbruch geben. Dann matchen wir innerhalb des Items (!) auf category
. Dem Inhalt dieser Felder stellen wir jeweils einen Spiegelstrich voran, die Zeile beenden wir wieder mit dem Zeilenumbruch. So sieht das Kommando dann fertig aus:
1 2 3 |
wget -qO - http://www.schatenseite.de/feed/ | \ xmlstarlet sel -t -m '//rss/channel/item[1]' -v title -n \ -m category -v 'concat(" - ", self::category)' -n |
Das Netz hält einige Artikel mit Beispielen parat, aber genau wie dieser Text kratzen die nur an der Oberfläche. XMLStarlet ist sicher ein Spielzeug mit dem man sich bei Gelegenheit mal länger auseinandersetzen sollte. Zumindest macht es den Standard-Werkzeugkasten im Umgang mit XML-Daten absolut obsolet.