JC: Wandelt die Ausgabe beliebter Kommandozeilen-Tools in JSON um
(github.com/kellyjonbrazil)- JC ist ein Tool, das die Ausgabe vieler CLI-Tools, Dateiformate und einfacher Strings in JSON umwandelt, damit sie in Skripten leichter geparst werden kann
- Es nimmt Pipe-Eingaben entgegen und gibt JSON über
STDOUTaus; außerdem unterstützt es eine Magic Syntax, bei derjcwie injc dig example.comvor einen Befehl gesetzt wird - Die Standardausgabe verwendet ein parser-spezifisches striktes Schema und wandelt Zahlen,
null, boolesche Werte sowie zusätzliche semantische Felder um; mit-roderraw=Truelässt sich auf das rohe JSON vor der Vorverarbeitung zugreifen - Es kann auch als Python-Bibliothek verwendet werden, sodass Ergebnisse statt als JSON als Python-Dictionary, Liste von Dictionaries oder als lazy Iterable zurückgegeben werden können
- Für große und lang laufende Pipelines bietet es Streaming-Parser, die JSON Lines/NDJSON ausgeben, außerdem
--slurp,--meta-out, lokale Parser-Plugins und Optionen zum Unterdrücken von Plattform-Kompatibilitätswarnungen
Was JC macht
- JC(JSON Convert) wandelt die Ausgabe vieler CLI-Tools, Dateiformate und einfacher Strings in JSON um
- Die konvertierte Ausgabe kann per Pipe an Tools wie
jqoderjellozur weiteren Verarbeitung übergeben werden - Ein Beispiel ist
dig example.com | jc --dig, das diedig-Ausgabe in ein JSON-Array umwandelt, gefolgt vonjq -r '.[].answer[].data', um nur die IP-Adressen zu extrahieren - Dieselbe Aufgabe lässt sich auch mit der Magic Syntax ausführen, etwa
jc dig example.com | jq -r '.[].answer[].data'
Nutzung als CLI und Python-Bibliothek
- Die grundlegende CLI-Nutzung besteht darin, Pipe-Eingaben entgegenzunehmen und eine JSON-Darstellung auszugeben
COMMAND | jc [SLICE] [OPTIONS] PARSERcat FILE | jc [SLICE] [OPTIONS] PARSERecho STRING | jc [SLICE] [OPTIONS] PARSER
- Bei der Magic Syntax wird
jcvor einen Befehl oder eine/proc-Datei gesetzt, im Formatjc [SLICE] [OPTIONS] COMMANDoderjc [SLICE] [OPTIONS] /proc/<path-to-procfile>- Befehls-Aliase und Shell-Builtins werden nicht unterstützt
- In Python wird es etwa mit
jc.parse('dig', cmd_output)aufgerufen- Der Rückgabewert kann statt eines JSON-Strings ein Python-Dictionary, eine Liste von Dictionaries oder bei Streaming-Parsern ein lazy Iterable sein
- Die Dokumentation zum Python-Paket ist über
help('jc'),help('jc.lib')oder in der Online-Dokumentation verfügbar
Ausgabedarstellung und Schema
- Die Standarddarstellung verwendet ein parser-spezifisches striktes Schema
- Bekannte Zahlen werden in JSON-Werte vom Typ
intoderfloatumgewandelt - Bekannte
None-Werte werden in JSONnullumgewandelt - Bekannte boolesche Werte werden ebenfalls umgewandelt
- Einige Parser fügen zusätzliche semantische Felder hinzu
- Bekannte Zahlen werden in JSON-Werte vom Typ
- Auf das rohe, vorverarbeitete JSON kann über die CLI-Option
-roder in der Python-Bibliothek mitparse(..., raw=True)zugegriffen werden - Die Schemata der einzelnen Parser sind über die Dokumentationslinks neben der Parser-Liste einsehbar
- Die JSON-Ausgabe ist standardmäßig kompakt; mit der Option
-pist ein Pretty Format möglich - Mit den Optionen
-yoder--yaml-outist auch eine YAML-Ausgabe möglich
Unterstützte Parser und Anwendungsbeispiele
- Unterstützt werden CLI-Befehle, Dateiformate und String-Parser
- Die Parser-Liste im README enthält unter anderem Dateien und Formate rund um
dig,ls,ping,ps,netstat,ifconfig,csv,xml,yaml,/etc/hosts,/etc/passwd,/proc/,systemctl,git log,jwt,url,semverundx509 - Beispielausgaben zeigen, wie verschiedene Eingaben in JSON-Strukturen umgewandelt werden
arp-Ausgaben werden in Felder für Adresse, Hardware-Typ, MAC-Adresse und Interface umgewandelt- CSV-Dateien werden in ein Array von Objekten umgewandelt, bei denen die Header als Schlüssel dienen
/etc/hostswird in IPs und Hostname-Arrays umgewandeltifconfigwird in ein Objekt umgewandelt, das Interface-Namen, MTU, IPv4-/IPv6-Adressen sowie Paket- und Byte-Zähler enthältpingwird in ein Objekt umgewandelt, das die Anzahl gesendeter und empfangener Pakete, Verlustrate, Round-Trip-Zeiten und eine Liste der Antworten enthält
- In Ansible kann es als Filter Plugin der Collection
community.generalverwendet werden
Installation
jckann auf verschiedene Arten installiert werdenpip3 install jc- OS-Paket-Repositories
- Architektur-spezifische Binaries aus den GitHub Releases
- Beispiele für Installationen über OS-Pakete sind:
- Debian/Ubuntu:
apt-get install jc - Fedora:
dnf install jc - openSUSE:
zypper install jc - Arch:
pacman -S jc - macOS:
brew install jc - FreeBSD: Installation über Ports
- Ansible Filter Plugin:
ansible-galaxy collection install community.general - FortiSOAR Connector: Installation aus dem FortiSOAR Connector Marketplace
- Debian/Ubuntu:
Wichtige Optionen
-a/--about: Gibt Informationen zujcund den Parsern als JSON oder YAML aus-d/--debug: Gibt bei Parsing-Problemen Trace-Meldungen aus;-ddbietet ausführlicheres Debugging-h/--help: Gibt die Hilfe aus; mitjc -h --parser_namewird die Parser-Dokumentation angezeigt-M/--meta-out: Fügt der Ausgabe Metadaten wie Zeitstempel, Parser-Name, Magic Command und Exit-Code des Magic Command hinzu-q/--quiet: Unterdrückt Parser-Warnmeldungen;-qqignoriert Fehler von Streaming-Parsern-s/--slurp: Fasst mehrzeilige Eingaben zu einem Array zusammen-u/--unbuffer: Deaktiviert Output-Buffering-B/--bash-comp,-Z/--zsh-comp: Erzeugt ein Completion Script für Bash oder Zsh
Slice und Slurp
- Slice verarbeitet mit einer Python-Slicing-ähnlichen
START:STOP-Syntax nur einen Teil der Eingabezeilen - Bei einer Tabelle mit Header und Footer lassen sich zum Beispiel mit
jc 1:-1 --asciitableoderjc 1:4 --asciitablenur die mittleren Daten in JSON umwandeln - Positive und leere Slices sind am speichereffizientesten, negative Slices verbrauchen mehr Speicher
- Slurp ist eine Funktion, mit der String-Parser, die einzeilige Eingaben erwarten, mehrere Einträge auf einmal als Array ausgeben können
- Beispiel: Eine Datei mit mehreren IP-Adressen, jeweils eine pro Zeile, wird mit
jc --slurp --ip-addressverarbeitet
- Beispiel: Eine Datei mit mehreren IP-Adressen, jeweils eine pro Zeile, wird mit
- Die
/proc-Magic-Syntax unterstützt bei Auswahl mehrerer Dateien automatisch Slurp- Werden mehrere
/proc-Dateien konvertiert, wird ein_file-Feld hinzugefügt, damit erkennbar ist, zu welcher Datei das jeweilige Ergebnisobjekt gehört
- Werden mehrere
- Wird
--meta-outzusammen mit Slurp verwendet, wird eine Struktur ausgegeben, die aus einemresult-Array und einem_jc_meta-Objekt besteht
Exit-Codes und Metadaten
- Schwerwiegende interne Fehler in
jcerzeugen den Exit-Code100; andernfalls wird0zurückgegeben - Bei Nutzung der Magic Syntax speichert
jcden Exit-Code des zu parsenden Programms und addiert ihn zum Exit-Code vonjc- Wenn
ifconfig1undjc0zurückgibt, ist der kombinierte Exit-Code1 - Wenn
ifconfig0undjc100zurückgibt, ist der kombinierte Exit-Code100 - Wenn beide Fehler liefern, ist der kombinierte Exit-Code
101
- Wenn
- Wird bei der Magic Syntax
--meta-outoder-Mverwendet, enthält das_jc_meta-Objekt Informationen zum Magic Command und dessen Exit-Code
Farben und Umgebungsvariablen
- Mit der Umgebungsvariable
JC_COLORSlassen sich Farben für key name, keyword, number und string festlegen- Das Format lautet
JC_COLORS=<keyname_color>,<keyword_color>,<number_color>,<string_color> - Farbwerte sind einer der folgenden Werte:
black,red,green,yellow,blue,magenta,cyan,gray,brightblack,brightred,brightgreen,brightyellow,brightblue,brightmagenta,brightcyan,white,default
- Das Format lautet
- Wird die Umgebungsvariable
NO_COLORgesetzt, wird farbige Ausgabe deaktiviert - Die Option
-Cerzwingt farbige Ausgabe und hat Vorrang vor der UmgebungsvariableNO_COLORsowie der Option-m
Streaming-Parser
- Die meisten Parser lesen die gesamte
STDINin den Speicher, parsen sie und serialisieren anschließend ein JSON-Dokument als Ausgabe - Einige Streaming-Parser verarbeiten Eingaben zeilenweise, sobald sie eingehen, und geben JSON Lines oder NDJSON aus
- Beispiele:
ls-s,ping-s - Bei großen Befehlsausgaben wie
ls -lR /kann der Speicherverbrauch stark reduziert werden, und in manchen Fällen kann die Verarbeitung schneller sein
- Beispiele:
- Streaming-Parser können nicht zusammen mit der Magic Syntax verwendet werden
- Damit Parsing-Fehler in lang laufenden Pipelines die Pipe nicht unterbrechen, kann
-qqoder in Pythonignore_exceptions=Trueverwendet werden- Erfolgreiche Zeilen enthalten
_jc_meta.success: true - Fehlgeschlagene Zeilen enthalten
_jc_meta.success: falsesowie die Feldererrorundline
- Erfolgreiche Zeilen enthalten
- Wenn Ausgaben zwischen Pipes wegen Betriebssystem-Puffern verzögert erscheinen, kann mit
-uunbuffered output genutzt werden- Bei großen Datenströmen kann unbuffered output jedoch langsamer sein
- In Python nehmen Streaming-Parser iterable Eingaben entgegen und geben iterable Objekte zurück, sodass eine lazy Verarbeitung möglich ist
Parser-Plugins
- Lokale Parser Plugins können im Ordner
jc/jcparsersdes App-Datenverzeichnisses abgelegt werden- Linux/unix:
$HOME/.local/share/jc/jcparsers - macOS:
$HOME/Library/Application Support/jc/jcparsers - Windows:
$LOCALAPPDATA\jc\jc\jcparsers
- Linux/unix:
- Plugins sind normale Python-Moduldateien
- Als Vorlage können
jc/parsers/foo.pyoderjc/parsers/foo_s.pyverwendet werden - Der Dateiname eines Plugins muss ein gültiger Python-Modulname sein, mit einem Buchstaben beginnen und darf nur alphanumerische Zeichen sowie Underscores enthalten
- Lokale Plugins können Standard-Parser überschreiben
Locale, Zeitzone und Kompatibilität
- Für beste Ergebnisse wird empfohlen,
LC_ALLaufCoderen_US.UTF-8zu setzen - Auf einigen älteren Systemen unterstützt die Locale
Ckeine UTF-8-Kodierung, sodass UTF-8-Ausgaben auf ASCII und\\u-Escape-Sequenzen zurückfallen können - Einige Parser fügen berechnete Epoch-Timestamp-Felder hinzu
- Wenn der Feldname kein
_utc-Suffix hat, gilt er als naive timestamp auf Basis der lokalen Zeitzone - Wird die UTC-Zeitzone im Text der Befehlsausgabe erkannt, wird daraus ein timezone aware timestamp, und der Schlüsselname erhält das Suffix
_utc - Andere Zeitzonen als UTC werden nicht als aware timestamp unterstützt
- Wenn der Feldname kein
- Einige Parser konvertieren plattformspezifische Ausgaben und geben eine Warnung aus, wenn sie auf einer nicht unterstützten Plattform ausgeführt werden
- Auch auf nicht unterstützten Plattformen können Ausgabedateien anderer Systeme geparst werden; dabei lassen sich Warnungen mit
-qoder in Python mitquiet=Trueunterdrücken - Zu den getesteten Plattformen gehören Centos 7.7, Ubuntu 18.04/20.04, Fedora32, macOS 10.11.6/10.14.6, NixOS, FreeBSD12, Windows 10, Windows 2016 Server und Windows 2019 Server
1 Kommentare
Meinungen auf Hacker News
Unter FreeBSD ist dieses Problem mit libxo bis zu einem gewissen Grad gelöst:
Man kann strukturierte Ausgabe wie mit
$ ps --libxo=json | jqerhalten.Perfekt ist es nicht: Unterstützung für
lsgab es einmal, wurde aber aus irgendeinem Grund entfernt, und nicht alle Utilities unterstützen es.jcwirkt wie eine gute Übergangslösung, die Parser für viele Befehle bereitstellt, hat aber die grundsätzliche Einschränkung, Textausgaben zu parsen, die ursprünglich nicht zum Parsen entworfen wurden.Es wäre schön, wenn sich Utilities darauf einigen würden, über ein gemeinsames Flag strukturierte Ausgabe zu liefern; auch wenn ein Standard wie bei PowerShell für Unix/Linux wohl zu weit ginge, wäre schon ein standardmäßiges
--json-Flag ein großer Fortschritt.https://wiki.freebsd.org/LibXo
https://reviews.freebsd.org/D13959
Soweit ich es verstehe, werden nicht nur strukturierte Daten weitergereicht, sondern undurchsichtige Objekte durch die Pipeline geschickt, auf denen man auch Methoden aufrufen kann, die auf frühere Stufen zurückwirken: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_methods?view=powershell-7.4
Wrapper wie
jc,libxound experimentelle Shells wie https://www.nushell.sh/ gefallen mir ebenfalls, aber sie konzentrieren sich eher auf Datentransport als auf Objekte mit ausführbaren Methoden.Strukturierte Daten fühlen sich weiterhin Unix-artig an; wenn man echte Objekte braucht, ist es meiner Ansicht nach Zeit, Python oder Ruby zu starten.
Egal wie gut eine Shell ist und wie gut ihre Programmierfunktionen sind: Wichtig ist zu wissen, wann man von Shell-Skripten zu einer vollwertigen Programmiersprache wechseln sollte.
jcwird dort als Werkzeug vorgestellt, das diese Lücke vorerst füllt, und liest sich als Brücke, bis sich-j/--json-Unterstützung in Unix-Tools allgemein verbreitet hat.https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/
/procähnlich keine unstrukturierten Textdateien zurück, sondern JSON-Daten.Eine stärker strukturelle Lösung könnte darin bestehen, Datenstrukturen aus ELF heraus exportierbar zu machen, diese Datenstrukturen für die Terminalausgabe zu serialisieren und sie dann in vom Nutzer gewünschten Formaten wie JSON oder YAML auszugeben oder weiterzuverarbeiten.
Ich erinnere mich nicht mehr an das genaue Utility, vermutlich war es
iostat, aber es formatierte JSON-Ausgabezeilen per String-Interpolation und erzeugte bei bestimmten Flag-Kombinationen völlig kaputte Ausgabe.Ich weiß nicht, ob das inzwischen besser ist, aber bei einer Intervalloption hätte ich eine Art JSON Lines erwartet.
In Sachen Benutzbarkeit sehe ich PowerShell und kubectl libxo weit voraus.
https://github.com/Juniper/libxo
https://libxo.readthedocs.io/en/latest/
Die Idee ist wirklich gut, aber beim Gedanken an die Wartung werde ich nervös.
Wenn man Versionsunterschiede, Ausgabeänderungen durch Befehls-Flags usw. berücksichtigt, sieht das nach Wartungshölle aus; in der Praxis wird es in manchen Fällen gut funktionieren, aber jenseits einfacher Standardfälle dürfte der Reiz schnell verfliegen.
Außerdem wirkt es nicht gut,
--für Tool-Optionen zu verwenden.Wenn jeder neue Parser ein neues Flag braucht, könnten Hilfeausgaben oder Manpages Tausende Zeilen lang werden.
Sobald ein Utility einen eigenen JSON-Export unterstützt, kann dieses Tool später einfach an diese Funktion delegieren.
jcvor den Befehl setzt, etwajc ls.Der Parameter
--cmdist sogar eine gute Idee, weil er erlaubt, Daten vor der Umwandlung zu bearbeiten.Zum Beispiel möchte man die Liste vor der Konvertierung vielleicht durch
grepschicken.Auch aus Wartungssicht gilt: Wenn sich die Ausgabe grundlegender Unix-Befehle stark ändert, zerbricht das nicht nur dieses Tool, sondern auch zahllose Skripte; deshalb dürfte es durch Updates anderer Binaries nicht so oft kaputtgehen, wie man zunächst denkt.
Ein gut gepflegtes gemeinsames Parser-Bündel ist besser als überall verstreute Ad-hoc-Parser für Ausgaben; wenn man aber etwas Komplexes tun will und deshalb direkte JSON-Ausgabe braucht, sollte das Parsen selbst dem Problem möglichst nichts hinzufügen.
Um das bequem zu nutzen, müsste ich wohl für alles, was ich verwenden will, zusätzliche Testfälle als PR einreichen.
Diese Tests hätte ich ohnehin selbst schreiben müssen.
Es geht kaum anders, als dass Leute Parsing-Informationen für die benötigten Tools einreichen und Nutzer sie leicht aktuell halten können.
Nushell verfolgt zwar einen anderen Ansatz, landet aber größtenteils am selben Punkt: strukturierte Daten aus Shell-Befehlen
Meist übernimmt die Shell selbst diese Rolle
http://www.nushell.sh/
from json-Operation und passt daher tatsächlich gut zu JCIch habe früher ein Video aufgenommen, das einige gute Funktionen von Nushell zeigt; etwa bei Minute 19 geht es um die Kombination mit
jc: https://www.youtube.com/watch?v=KF5dtxVsn1EIch wollte gerade ein Skript schreiben, das Dateien in Verzeichnissen nach einem bestimmten Muster durchsucht und diejenigen entfernt, deren Änderungszeiten innerhalb von 10 Minuten voneinander liegen, als mir einfiel, dass Nushell für solche Dinge gut geeignet ist
Nach kurzem Herumprobieren hat es endlich Klick gemacht, und jetzt bin ich ziemlich begeistert
Selbst bei unstrukturierten Daten ist es sehr mächtig, wenn man sie in etwas wie eine Liste von Records umwandeln und dann verarbeiten kann
In gewisser Weise ist es großartig, dass überall Dateien sind; das ist das Unix-Versprechen, und in Plan 9 wurde es noch weiter ausgebaut
Aber unstrukturierte Dateien oder Dateien mit jeweils eigenen Formaten bremsen einen genauso stark aus
Schon der Versuch, eine einzelne nginx-Logdatei nur mit etwas wie
awkzu parsen, kann lästig seinEiner der großen Nachteile ist, dass es im Linux-Userspace schwer ist, groß angelegte Systemneuschreibungen oder Designänderungen umzusetzen
Ich wünsche mir eine intelligentere Shell, ich mag Dateien, und auch das
awk-Buch liegt neben mir, aber inzwischen ist es an der Zeit für ernsthafte Verbesserungen beim DatenparsingSo wie Programme selbst entscheiden können, ob sie farbige Ausgabe rendern sollen, wäre es gut, wenn sie auch strukturierte Ausgabe liefern könnten
Jede Text-UI kann wie eine API verwendet werden, deshalb bekommt menschenlesbarer Text Priorität
Shell-Scripting ähnelt daher dem Erstellen von Browser-Erweiterungen von Drittanbietern
Man schaut hin, stellt Vermutungen an, bastelt auf dieser Grundlage schnell einen Parser zusammen und hofft, dass es funktioniert
Es wäre gut, einen dritten Standard-Ausgabekanal für maschinenlesbare Inhalte zu haben
Das Terminal würde ihn standardmäßig nicht ausgeben; beim Piping würde diese Ausgabe weitergeleitet, sie sollte JSONL sein, und die Manpage würde den Vertrag festschreiben
Dann könnte stdout für Menschen bleiben, und wenn man es parst, wüsste man, dass es zwar möglich, aber fragil ist
Natürlich wäre das eine völlig rückwärtsinkompatible Idee, und wenn man die CLI unrealistisch von Grund auf neu erfinden und modernisieren würde, gäbe es eine lange Liste von Dingen, die man ändern wollte
Verbesserungen durchzusetzen ist auch wirklich schwer, und wenn jemand wie Lennart versucht, jahrzehntealten alten Ballast wegzuräumen, gibt es sofort Drama
Auch JSON ist noch nicht vollkommen
JSON ist eine halbwegs gute Idee, aber wenn man es richtig machen will, braucht man ein Format, das Dinge wie Datentypen sichtbar machen kann
Es müsste eher in Richtung PowerShell gehen, damit man Zahlen als Zahlen behandelt und erstaunliche Dinge wie die Berechnung der Differenz zwischen Datumswerten mit
$a - $bmachen kannEs wäre schön, wenn das in den GNU coreutils umgesetzt würde
Das Problem ist, dass sie so tief in .NET und Objekten verwurzelt ist, dass die Integration mit bestehenden nativen Befehlen auf jeder Plattform sehr schwierig ist
Denn im Kern machen sie bereits dasselbe
Das Endziel dürfte aber letztlich sein, dass übergeordnete Tools den Wert erkennen und selbst strukturierte Ausgabe bereitstellen
Schön
Ich unterstütze CLI-Tools mit sinnvoller JSON-Ausgabe sehr, und Dinge wie https://github.com/WireGuard/wireguard-tools/blob/master/contrib/json/wg-json sowie PowerShells
|ConvertTo-Jsonmachen einen großen Teil der Verwaltungs-/Monitoring-Automatisierung ausAllerdings leistet das Wort sinnvoll hier viel Arbeit, und die Realität ist nun einmal die Realität
Wie bei LSI/Broadcom StorCLI, wo man ein
Jan den Befehl anhängt, oder bei PowerShells COM-verbergenden Wrappern ist es zwar technisch JSON, aber das Ergebnis ist oft absurd kompliziert oder nutzlos, sodass man am Ende doch wieder zum Provisorium „einfach ein paar Regexes über die Klartextausgabe laufen lassen“ zurückkehrtTrotzdem werde ich mir das auf jeden Fall ansehen
Wenn das erste Beispiel, das Parsen der
dig-Ausgabe, repräsentativ für Dinge ist, die sich stabil erledigen lassen, könnte das ziemlich interessant seinIch finde,
jc dig example.comsollte die Standardsyntax seinDenn bei
dig example.com | jc --digmuss man später die Flags und Parameter des vorherigen Befehls erraten, um die Ausgabe zu parsenDass jede Ausgabe ein Objekt ist, gehört zu meinen Lieblingsaspekten von PowerShell
Das vermisse ich jedes Mal, wenn ich ein bash-Skript schreiben muss
Respekt vor der Person, die sich vorgenommen hat, das zu warten
So etwas wie
aws s3 ls | jc --aws=1.2.3wäre ein AlbtraumDas erinnert mich an das
file-Programm unter Linux oder Unix und an die Heldinnen und Helden, die es pflegenpluginsladen ließe, zum Beispiel in Form separater Shell-Befehle, einen Teil des Wartungsaufwands an Plugin-Autoren weitergebenIch frage mich, ob es eine Liste moderner Unix-Kommandozeilentools gibt, die eine
--json-Option akzeptieren.Es könnte nützlich sein, solche Informationen zu diesem Repository hinzuzufügen.
ip, der moderne Ersatz fürifconfig, unterstützt JSON.lldpctlunterstützt es ebenfalls.Ansible stellt Systemdetails als JSON namens
factsbereit, und Automatisierung ist darauf ausgelegt, diese zu nutzen.lsblkakzeptiert das Flag--jsonund kann viele Informationen liefern.Man kann
lsblk --json --output-allausprobieren.Das ist sehr nützlich, wenn ein Skript die Festplatten und Partitionen eines Systems prüfen muss.
-T json.Interessantes Projekt.
Ich hätte allerdings erwartet, dass als Parser der ersten Stufe etwas wie textfsm verwendet wird.
textfsm wird häufig zum Parsen der CLI-Ausgabe von Netzwerkgeräten genutzt.
https://github.com/google/textfsm