JSON mit Unix-Tools analysieren

Ich versuche, JSON zu analysieren, das von einer Lock-Anforderung zurückgegeben wurde, wie folgt:

curl 'http://twitter.com/users/username.json' | sed -e 's/[{}]/''/g' | awk -vk="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' 

Das obige teilt den JSON in Felder auf, zum Beispiel:

 % ... "geo_enabled":false "friends_count":245 "profile_text_color":"000000" "status":"in_reply_to_screen_name":null "source":"web" "truncated":false "text":"My status" "favorited":false % ... 

Wie -vk=text ich ein bestimmtes Feld (bezeichnet mit dem -vk=text )?

Es gibt eine Reihe von Tools, die speziell für die Manipulation von JSON über die Kommandozeile entwickelt wurden und viel einfacher und zuverlässiger sind als mit Awk, wie jq :

 curl -s 'https://api.github.com/users/lambda' | jq -r '.name' 

Sie können dies auch mit Tools tun, die wahrscheinlich bereits auf Ihrem System installiert sind, wie Python mit dem json Modul , und so zusätzliche Abhängigkeiten vermeiden und dennoch den Vorteil eines geeigneten JSON-Parsers haben. Im Folgenden wird davon ausgegangen, dass Sie UTF-8 verwenden möchten, in dem der ursprüngliche JSON-Code codiert werden soll. Dies wird auch von den meisten modernen Terminals verwendet:

Python 2:

 export PYTHONIOENCODING=utf8 curl -s 'https://api.github.com/users/lambda' | \ python -c "import sys, json; print json.load(sys.stdin)['name']" 

Python 3:

 curl -s 'https://api.github.com/users/lambda' | \ python3 -c "import sys, json; print(json.load(sys.stdin)['name'])" 

Historische Notizen

Diese Antwort empfahl ursprünglich jsawk , was noch funktionieren sollte, ist aber ein wenig mühsamer als jq und hängt von einem eigenständigen installierten JavaScript-Interpreter ab, der weniger verbreitet ist als ein Python-Interpreter. jq sind die obigen Antworten wahrscheinlich vorzuziehen:

 curl -s 'https://api.github.com/users/lambda' | jsawk -a 'return this.name' 

Diese Antwort verwendete ursprünglich auch die Twitter-API aus der Frage, aber diese API funktioniert nicht mehr, was es schwierig macht, die Beispiele zum Testen zu kopieren, und die neue Twitter-API benötigt API-Schlüssel. Daher habe ich die GitHub-API verwendet kann ohne API-Schlüssel einfach verwendet werden. Die erste Antwort für die ursprüngliche Frage wäre:

 curl 'http://twitter.com/users/username.json' | jq -r '.text' 

Um die Werte für einen bestimmten Schlüssel schnell zu extrahieren, benutze ich gerne “grep -o”, was nur die Übereinstimmung des Regex zurückgibt. Um zum Beispiel das “Text” -Feld aus Tweets zu erhalten:

 grep -Po '"text":.*?[^\\]",' tweets.json 

Diese Regex ist robuster als Sie vielleicht denken; Zum Beispiel geht es gut mit Strings, die eingebettete Kommas enthalten und Zitate in ihnen enthalten. Ich denke, mit ein wenig mehr Arbeit könnte man einen machen, der garantiert den Wert extrahiert, wenn es atomar ist. (Wenn es verschachtelt ist, kann eine Regex das natürlich nicht machen.)

Und um weiter zu putzen (auch wenn das ursprüngliche Original der Saite erhalten bleibt), können Sie etwas wie: | perl -pe 's/"text"://; s/^"//; s/",$//' | perl -pe 's/"text"://; s/^"//; s/",$//' | perl -pe 's/"text"://; s/^"//; s/",$//' . (Ich habe das für diese Analyse getan.)

Um alle Hasser, die darauf bestehen, sollten Sie einen echten JSON-Parser verwenden – ja, das ist essentiell für die Richtigkeit, aber

  1. Um eine wirklich schnelle Analyse durchzuführen, z. B. das Zählen von Werten, um Fehler bei der Datenbereinigung zu überprüfen oder ein allgemeines Gefühl für die Daten zu bekommen, ist es schneller, etwas in der Befehlszeile auszufallen. Das Öffnen eines Editors zum Schreiben eines Skripts ist störend.
  2. grep -o ist um Größenordnungen schneller als die Python-Standard- json Bibliothek, zumindest dann, wenn dies für Tweets geschieht (die jeweils ~ 2 KB groß sind). Ich bin mir nicht sicher, ob dies nur weil json ist langsam (ich sollte irgendwann yajl vergleichen); aber im Prinzip sollte ein Regex schneller sein, da es ein endlicher Zustand und viel besser optimierbar ist, anstelle eines Parsers, der Rekursion unterstützen muss, und in diesem Fall gibt es viele CPU-Baumstrukturen für Strukturen, die Sie nicht interessieren. (Wenn jemand einen endlichen Zustandswandler geschrieben hat, der richtiges (tiefenbegrenztes) JSON Parsing gemacht hat, wäre das fantastisch! In der Zwischenzeit haben wir “grep -o”.)

Um wartbaren Code zu schreiben, verwende ich immer eine echte Parsing-Bibliothek. Ich habe Jsawk nicht ausprobiert, aber wenn es gut funktioniert, würde das den Punkt Nr. 1 betreffen .

Eine letzte, verrücktere Lösung: Ich schrieb ein Skript, das Python json und die gewünschten Schlüssel in tab-getrennte Spalten extrahiert; dann awk ich einen Wrapper um awk , der named Zugriff auf Spalten erlaubt. Hier drin: die json2tsv und tsvawk Skripte . Also für dieses Beispiel wäre es:

 json2tsv id text < tweets.json | tsvawk '{print "tweet " $id " is: " $text}' 

Dieser Ansatz behandelt nicht # 2, ist ineffizienter als ein einzelnes Python-Skript und ist etwas spröde: Er zwingt die Normalisierung von Zeilenumbrüchen und Tabulatoren in Zeichenfolgenwerten, um mit awks Feld- / Datensatz-abgegrenzten Ansichten der Welt zu spielen. Aber es lässt dich auf der Kommandozeile bleiben, mit mehr Korrektheit als grep -o .

Auf der Grundlage, dass einige der Empfehlungen hier (vor allem in den Kommentaren) die Verwendung von Python nahelegten, war ich enttäuscht, kein Beispiel zu finden.

Also, hier ist ein Liner, um einen einzelnen Wert von einigen JSON-Daten zu erhalten. Es nimmt an, dass Sie die Daten in (von irgendwo) leiten und so in einem Skriptkontext nützlich sein sollten.

 echo '{"hostname":"test","domainname":"example.com"}' | python -c 'import json,sys;obj=json.load(sys.stdin);print obj[0]["hostname"]' 

Folgend MartinR und Boecko führen:

 $ curl -s 'http://twitter.com/users/username.json' | python -mjson.tool 

Das gibt dir eine extrem grep freundliche Ausgabe. Sehr angenehm:

 $ curl -s 'http://twitter.com/users/username.json' | python -mjson.tool | grep my_key 

Sie könnten einfach jq binary für Ihre Plattform herunterladen und ausführen ( chmod +x jq ):

 $ curl 'https://twitter.com/users/username.json' | ./jq -r '.name' 

Es extrahiert das "name" -Attribut aus dem json-Objekt.

jq Homepage sagt, es ist wie sed für JSON-Daten.

Verwenden Sie Pythons JSON-Unterstützung statt awk!

Etwas wie das:

 curl -s http://twitter.com/users/username.json | \ python -c "import json,sys;obj=json.load(sys.stdin);print obj['name'];" 

Verwenden von Node.js

Wenn auf dem System ein Knoten installiert ist, können Sie die Script-Flags -p print und -e evue mit JSON.parse , um alle erforderlichen JSON.parse zu JSON.parse .

Ein einfaches Beispiel, das den JSON-String { "foo": "bar" } und den Wert von “foo” herauszieht:

 $ node -pe 'JSON.parse(process.argv[1]).foo' '{ "foo": "bar" }' bar 

Da wir Zugriff auf cat und andere Dienstprogramme haben, können wir dies für Dateien verwenden:

 $ node -pe 'JSON.parse(process.argv[1]).foo' "$(cat foobar.json)" bar 

Oder ein anderes Format wie eine URL, die JSON enthält:

 $ node -pe 'JSON.parse(process.argv[1]).name' "$(curl -s https://api.github.com/users/trevorsenior)" Trevor Senior 

Sie haben gefragt, wie Sie sich in den Fuß schießen und ich bin hier, um die Munition zu liefern:

 curl -s 'http://twitter.com/users/username.json' | sed -e 's/[{}]/''/g' | awk -v RS=',"' -F: '/^text/ {print $2}' 

Sie könnten tr -d '{}' anstelle von sed . Aber sie komplett auszulassen, scheint auch den gewünschten Effekt zu haben.

Wenn Sie die äußeren Anführungszeichen entfernen möchten, leiten Sie das Ergebnis des obigen durch sed 's/\(^"\|"$\)//g'

Ich denke, andere haben genug Alarm geschlagen. Ich stehe mit einem Handy bereit, um einen Krankenwagen anzurufen. Feuer wenn fertig.

Verwenden von Bash mit Python

Erstellen Sie eine Bash-function in Ihrer .bash_rc-Datei

 function getJsonVal () { python -c "import json,sys;sys.stdout.write(json.dumps(json.load(sys.stdin)$1))"; } 

Dann

 $ curl 'http://twitter.com/users/username.json' | getJsonVal "['text']" My status $ 

Hier ist die gleiche function, aber mit Fehlerprüfung.

 function getJsonVal() { if [ \( $# -ne 1 \) -o \( -t 0 \) ]; then cat <  

Wobei $ # -ne 1 dafür sorgt, dass mindestens eine Eingabe erfolgt, und -t 0 stellt sicher, dass Sie von einer Pipe redirect.

Das Schöne an dieser Implementierung ist, dass Sie auf verschachtelte JSON-Werte zugreifen und JSON im Gegenzug erhalten können! =)

Beispiel:

 $ echo '{"foo": {"bar": "baz", "a": [1,2,3]}}' | getJsonVal "['foo']['a'][1]" 2 

Wenn Sie wirklich schick sein möchten, könnten Sie die Daten schön ausdrucken:

 function getJsonVal () { python -c "import json,sys;sys.stdout.write(json.dumps(json.load(sys.stdin)$1, sort_keys=True, indent=4))"; } $ echo '{"foo": {"bar": "baz", "a": [1,2,3]}}' | getJsonVal "['foo']" { "a": [ 1, 2, 3 ], "bar": "baz" } 

JSON mit PHP CLI analysieren

Wohl unpassend, aber da die Vorrangstellung vorherrscht, bleibt diese Frage unvollständig, ohne dass wir unsere treue und treue PHP erwähnen, oder?

Verwenden Sie dasselbe JSON-Beispiel, aber weisen Sie es einer Variablen zu, um Unklarheiten zu vermeiden.

 $ export JSON='{"hostname":"test","domainname":"example.com"}' 

Jetzt für PHP-Güte, mit file_get_contents und dem php: // stdin stream wrapper.

 $ echo $JSON|php -r 'echo json_decode(file_get_contents("php://stdin"))->hostname;' 

oder, wie mit fgets und dem bereits geöffneten Stream bei CLI-Konstante STDIN angegeben .

 $ echo $JSON|php -r 'echo json_decode(fgets(STDIN))->hostname;' 

NJoy!

TickTick ist ein in bash geschriebener JSON Parser (<250 Zeilen Code)

Hier ist der Ausschnitt des Autors aus seinem Artikel: Stellen Sie sich eine Welt vor, in der Bash JSON unterstützt :

 #!/bin/bash . ticktick.sh `` people = { "Writers": [ "Rod Serling", "Charles Beaumont", "Richard Matheson" ], "Cast": { "Rod Serling": { "Episodes": 156 }, "Martin Landau": { "Episodes": 2 }, "William Shatner": { "Episodes": 2 } } } `` function printDirectors() { echo " The ``people.Directors.length()`` Directors are:" for director in ``people.Directors.items()``; do printf " - %s\n" ${!director} done } `` people.Directors = [ "John Brahm", "Douglas Heyes" ] `` printDirectors newDirector="Lamont Johnson" `` people.Directors.push($newDirector) `` printDirectors echo "Shifted: "``people.Directors.shift()`` printDirectors echo "Popped: "``people.Directors.pop()`` printDirectors 

Native Bash-Version: functioniert auch gut mit Backslashes (\) und Anführungszeichen (“)

 function parse_json() { echo $1 | \ sed -e 's/[{}]/''/g' | \ sed -e 's/", "/'\",\"'/g' | \ sed -e 's/" ,"/'\",\"'/g' | \ sed -e 's/" , "/'\",\"'/g' | \ sed -e 's/","/'\"---SEPERATOR---\"'/g' | \ awk -F=':' -v RS='---SEPERATOR---' "\$1~/\"$2\"/ {print}" | \ sed -e "s/\"$2\"://" | \ tr -d "\n\t" | \ sed -e 's/\\"/"/g' | \ sed -e 's/\\\\/\\/g' | \ sed -e 's/^[ \t]*//g' | \ sed -e 's/^"//' -e 's/"$//' } parse_json '{"username":"john, doe","email":"john@doe.com"}' username parse_json '{"username":"john doe","email":"john@doe.com"}' email --- outputs --- john, doe johh@doe.com 

Version, die Ruby und http://flori.github.com/json/ verwendet

 $ < file.json ruby -e "require 'rubygems'; require 'json'; puts JSON.pretty_generate(JSON[STDIN.read]);" 

oder prägnanter:

 $ < file.json ruby -r rubygems -r json -e "puts JSON.pretty_generate(JSON[STDIN.read]);" 

Sie können jshon :

 curl 'http://twitter.com/users/username.json' | jshon -e text 

Leider gibt die Antwort mit der höchsten Antwort, die grep verwendet, die vollständige Übereinstimmung zurück, die in meinem Szenario nicht funktioniert hat. Wenn Sie jedoch wissen, dass das JSON-Format konstant bleibt, können Sie mit lookbehind und lookahead nur die gewünschten Werte extrahieren.

 # echo '{"TotalPages":33,"FooBar":"he\"llo","anotherValue":100}' | grep -Po '(?< ="FooBar":")(.*?)(?=",)' he\"llo # echo '{"TotalPages":33,"FooBar":"he\"llo","anotherValue":100}' | grep -Po '(?<="TotalPages":)(.*?)(?=,)' 33 # echo '{"TotalPages":33,"FooBar":"he\"llo","anotherValue":100}' | grep -Po '(?<="anotherValue":)(.*?)(?=})' 100 

Hier ist eine Möglichkeit, wie Sie es mit Awk tun können

 curl -sL 'http://twitter.com/users/username.json' | awk -F"," -vk="text" '{ gsub(/{|}/,"") for(i=1;i< =NF;i++){ if ( $i ~ k ){ print $i } } }' 

Jemand, der auch XML-Dateien hat, möchte vielleicht meinen Xidel ansehen . Es ist ein CLI-abhängiger JSONiq- processor. (dh es unterstützt auch XQuery für XML oder JSON-Verarbeitung)

Das Beispiel in der Frage wäre:

  xidel -e 'json("http://twitter.com/users/username.json")("name")' 

Oder mit meiner eigenen, nicht standardmäßigen Erweiterungssyntax:

  xidel -e 'json("http://twitter.com/users/username.json").name' 

Für komplexere JSON-Parsing empfehle ich Python jsonpath-Modul (von Stefan Goessner) –

  1. Es installieren –

sudo easy_install -U jsonpath

  1. Benutze es –

Beispiel file.json (von http://goessner.net/articles/JsonPath ) –

 { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "JRR Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } } 

Parsen Sie es (extrahieren Sie alle Buchtitel mit dem Preis <10) -

 $ cat file.json | python -c "import sys, json, jsonpath; print '\n'.join(jsonpath.jsonpath(json.load(sys.stdin), 'store.book[?(@.price < 10)].title'))" 

Wird ausgegeben -

 Sayings of the Century Moby Dick 

Hinweis: die obige Befehlszeile enthält keine Fehlerüberprüfung. Für eine vollständige Lösung mit Fehlerüberprüfung sollten Sie ein kleines Python-Skript erstellen und den Code mit try-except umhüllen.

Wenn Sie PHP haben :

 php -r 'var_export(json_decode(`curl http://twitter.com/users/username.json`, 1));' 

Beispielsweise:
Wir haben eine Ressource, die JSON mit Ländern ISO-Codes zur Verfügung stellt: http://country.io/iso3.json und wir können es leicht in einer Shell mit curl sehen:

 curl http://country.io/iso3.json 

aber es sieht nicht sehr praktisch, und nicht lesbar, besser json json und lesbare struktur zu sehen:

 php -r 'var_export(json_decode(`curl http://country.io/iso3.json`, 1));' 

Dieser Code wird etwa so aussehen:

 array ( 'BD' => 'BGD', 'BE' => 'BEL', 'BF' => 'BFA', 'BG' => 'BGR', 'BA' => 'BIH', 'BB' => 'BRB', 'WF' => 'WLF', 'BL' => 'BLM', ... 

Wenn Sie verschachtelte Arrays haben, wird diese Ausgabe viel besser aussehen …

Hoffe, das wird hilfreich …

Jetzt, da Powershell plattformübergreifend ist, dachte ich, ich würde mich da rauskämpfen, da ich finde, dass es ziemlich intuitiv und extrem einfach ist.

 curl -s 'https://api.github.com/users/lambda' | ConvertFrom-Json 

ConvertFrom-Json konvertiert den JSON in ein benutzerdefiniertes PowerShell-Objekt, sodass Sie ab diesem Zeitpunkt problemlos mit den Eigenschaften arbeiten können. Wenn Sie zum Beispiel nur die Eigenschaft ‘id’ möchten, tun Sie das einfach:

 curl -s 'https://api.github.com/users/lambda' | ConvertFrom-Json | select -ExpandProperty id 

Wenn du das Ganze von Bash aus aufrufen willst, dann musst du es so nennen:

 powershell 'curl -s "https://api.github.com/users/lambda" | ConvertFrom-Json' 

Natürlich gibt es eine pure Powershell-Art, es ohne Curl zu machen, das wäre:

 Invoke-WebRequest 'https://api.github.com/users/lambda' | select -ExpandProperty Content | ConvertFrom-Json 

Schließlich gibt es noch “ConvertTo-Json”, das ein benutzerdefiniertes Objekt genauso einfach in JSON konvertiert. Hier ist ein Beispiel:

 (New-Object PsObject -Property @{ Name = "Tester"; SomeList = @('one','two','three')}) | ConvertTo-Json 

Was würde schöne JSON wie folgt produzieren:

 { "Name": "Tester", "SomeList": [ "one", "two", "three" ] 

}

Zugegeben, die Verwendung einer Windows-Shell unter Unix ist etwas Sakrileg, aber Powershell ist wirklich gut in einigen Dingen, und die Analyse von JSON und XML sind ein paar von ihnen. Dies ist die GitHub-Seite für die plattformübergreifende Version https://github.com/PowerShell/PowerShell

Sie können so etwas ausprobieren –

 curl -s 'http://twitter.com/users/jaypalsingh.json' | awk -F=":" -v RS="," '$1~/"text"/ {print}' 

Das Analysieren von JSON ist in einem Shell-Skript schmerzhaft. Erstellen Sie mit einer geeigneteren Sprache ein Tool, das JSON-Attribute auf eine Weise extrahiert, die den Shell-Skriptkonventionen entspricht. Sie können Ihr neues Tool verwenden, um das Problem der sofortigen Shell-Skripterstellung zu lösen, und es dann für zukünftige Situationen zu Ihrem Kit hinzufügen.

Betrachten wir zum Beispiel ein Tool jsonlookup , das, wenn ich jsonlookup access token id sage, die Attribut- ID jsonlookup access token id die innerhalb des Attributtokens definiert ist, das innerhalb des Attributzugriffs von stdin definiert ist, was vermutlich JSON-Daten sind. Wenn das Attribut nicht existiert, gibt das Werkzeug nichts zurück (Exit-Status 1). Wenn das Parsen fehlschlägt, beenden Sie Status 2 und eine Nachricht an stderr. Wenn die Suche erfolgreich ist, druckt das Tool den Wert des Attributs.

Nachdem Sie ein Unix-Tool für den genauen Zweck der JSON-Werte erstellt haben, können Sie es einfach in Shell-Skripten verwenden:

 access_token=$(curl  | jsonlookup access token id) 

Jede Sprache wird für die Implementierung von jsonlookup ausreichen . Hier ist eine ziemlich übersichtliche Python-Version:

 #!/usr/bin/python import sys import json try: rep = json.loads(sys.stdin.read()) except: sys.stderr.write(sys.argv[0] + ": unable to parse JSON from stdin\n") sys.exit(2) for key in sys.argv[1:]: if key not in rep: sys.exit(1) rep = rep[key] print rep 

Ein Zweiliner, der Python verwendet. Es funktioniert besonders gut, wenn Sie eine einzelne .sh-Datei schreiben und nicht auf eine andere .py-Datei angewiesen sind. Es nutzt auch die Verwendung von pipe | . echo "{\"field\": \"value\"}" kann durch irgendwas ersetzt werden, indem ein json auf das stdout gedruckt wird.

 echo "{\"field\": \"value\"}" | python -c 'import sys, json print(json.load(sys.stdin)["field"])' 

Dies ist ein guter Anwendungsfall für Pythonpy :

 curl 'http://twitter.com/users/username.json' | py 'json.load(sys.stdin)["name"]' 

Dies ist eine weitere bash & python Hybrid-Antwort. Ich habe diese Antwort gepostet, weil ich komplexere JSON-Ausgaben verarbeiten wollte, aber die Komplexität meiner Bash-Anwendung reduzieren wollte. Ich möchte das folgende JSON-Objekt von http://www.arcgis.com/sharing/rest/info?f=json in bash öffnen:

 { "owningSystemUrl": "http://www.arcgis.com", "authInfo": { "tokenServicesUrl": "https://www.arcgis.com/sharing/rest/generateToken", "isTokenBasedSecurity": true } } 

Während dieser Ansatz die Komplexität in der Python-function erhöht, wird die bash-Verwendung einfacher:

 function jsonGet { python -c 'import json,sys o=json.load(sys.stdin) k="'$1'" if k != "": for a in k.split("."): if isinstance(o, dict): o=o[a] if a in o else "" elif isinstance(o, list): if a == "length": o=str(len(o)) elif a == "join": o=",".join(o) else: o=o[int(a)] else: o="" if isinstance(o, str) or isinstance(o, unicode): print o else: print json.dumps(o) ' } curl -s http://www.arcgis.com/sharing/rest/info?f=json | jsonGet curl -s http://www.arcgis.com/sharing/rest/info?f=json | jsonGet authInfo curl -s http://www.arcgis.com/sharing/rest/info?f=json | jsonGet authInfo.tokenServicesUrl 

Die Ausgabe des obigen Skripts ist:

Ich habe Unterstützung für Arrays hinzugefügt, so dass Sie .length verwenden .length und, wenn die Quelle ein String-Array ist, können Sie .join :

 curl -s http://www.arcgis.com/sharing/rest/portals/self?f=pjson | jsonGet defaultBasemap.baseMapLayers.length curl -s http://www.arcgis.com/sharing/rest/portals/self?f=pjson | jsonGet defaultBasemap.baseMapLayers.0.resourceInfo.tileInfo.lods curl -s http://www.arcgis.com/sharing/rest/portals/self?f=pjson | jsonGet defaultBasemap.baseMapLayers.0.resourceInfo.tileInfo.lods.length curl -s http://www.arcgis.com/sharing/rest/portals/self?f=pjson | jsonGet defaultBasemap.baseMapLayers.0.resourceInfo.tileInfo.lods.23 

Welche Ausgänge:

  • 1
  • [{“scale”: 591657527.591555, “resolution”: 156543.03392800014, “level”: 0}, {“scale”: 295828763.795777, “resolution”: 78271.51696399994, “level”: 1}, {“skala”: 147914381.897889, “resolution “: 39135.75848200009, “level”: 2}, {“scale”: 73957190.948944, “resolution”: 19567.87924099992, “level”: 3}, {“scale”: 36978595.474472, “resolution”: 9783.93962049996, “level”: 4} , {“scale”: 18489297.737236, “resolution”: 4891.96981024998, “level”: 5}, {“scale”: 9244648.868618, “resolution”: 2445.98490512499, “level”: 6}, {“scale”: 4622324.434309, “resolution “: 1222.992452562495, “level”: 7}, {“scale”: 2311162.217155, “resolution”: 611.4962262813797, “level”: 8}, {“scale”: 1155581.108577, “resolution”: 305.74811314055756, “level”: 9} , {“scale”: 577790.554289, “resolution”: 152.87405657041106, “level”: 10}, {“scale”: 288895.277144, “resolution”: 76.43702828507324, “level”: 11}, {“scale”: 144447.638572, “resolution “: 38.21851414253662, “level”: 12}, {“scale”: 72223.819286, “resolution”: 19.1092570712683 1, “level”: 13}, {“scale”: 36111.909643, “resolution”: 9.554628535634155, “level”: 14}, {“scale”: 18055.954822, “resolution”: 4.77731426794937, “level”: 15}, {“scale”: 9027.977411, “resolution”: 2.388657133974685, “level”: 16}, {“scale”: 4513.988705, “resolution”: 1.1943285668550503, “level”: 17}, {“scale”: 2256.994353, “resolution”: 0.5971642835598172, “level”: 18}, {“scale”: 1128.497176, “resolution”: 0.29858214164761665, “level”: 19}, {“scale”: 564.248588, “resolution”: 0.14929107082380833, “level”: 20}, {“scale”: 282.124294, “resolution”: 0.07464553541190416, “level”: 21}, {“scale”: 141.062147, “resolution”: 0.03732276770595208, “level”: 22}, {“scale”: 70.5310735, “resolution”: 0.01866138385297604, “level”: 23}]
  • 24
  • {“scale”: 70.5310735, “resolution”: 0.01866138385297604, “level”: 23}

If someone just wants to extract values from simple JSON objects without the need for nested structures, it is possible to use regular expressions without even leaving the bash.

Here is a function I defined using bash regular expressions based on the JSON standard :

 function json_extract() { local key=$1 local json=$2 local string_regex='"([^"\]|\\.)*"' local number_regex='-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?' local value_regex="${string_regex}|${number_regex}|true|false|null" local pair_regex="\"${key}\"[[:space:]]*:[[:space:]]*(${value_regex})" if [[ ${json} =~ ${pair_regex} ]]; then echo $(sed 's/^"\|"$//g' < << "${BASH_REMATCH[1]}") else return 1 fi } 

Caveats: objects and arrays are not supported as value, but all other value types defined in the standard are supported. Also, a pair will be matched no matter how deep in the JSON document it is as long as it has exactly the same key name.

Using OP's example:

 $ json_extract text "$(curl 'http://twitter.com/users/username.json')" My status $ json_extract friends_count "$(curl 'http://twitter.com/users/username.json')" 245 

Here is a good reference . In diesem Fall:

 curl 'http://twitter.com/users/username.json' | sed -e 's/[{}]/''/g' | awk -vk="text" '{n=split($0,a,","); for (i=1; i< =n; i++) { where = match(a[i], /\"text\"/); if(where) {print a[i]} } }' 

If pip is avaiable on the system then:

 $ pip install json-query 

Examples of usage:

 $ curl -s http://0/file.json | json-query { "key":"value" } $ curl -s http://0/file.json | json-query my.key value $ curl -s http://0/file.json | json-query my.keys. key_1 key_2 key_3 $ curl -s http://0/file.json | json-query my.keys.2 value_2 

Niet is a tool that help you to extract data from json or yaml file directly in your shell/bash CLI.

 $ pip install niet 

Consider a json file named project.json with the following contents:

 { project: { meta: { name: project-sample } } 

You can use niet like this:

 $ PROJECT_NAME=$(niet project.json project.meta.name) $ echo ${PROJECT_NAME} project-sample 

i used this to extract video duration from ffprobe json output :

 MOVIE_INFO=`ffprobe "path/to/movie.mp4" -show_streams -show_format -print_format json -v quiet` MOVIE_SECONDS=`echo "$MOVIE_INFO"|grep -w \"duration\" |tail -1 | cut -d\" -f4 |cut -d \. -f 1` 

it can be used to extract value from any json :

 value=`echo "$jsondata"|grep -w \"key_name\" |tail -1 | cut -d\" -f4