Analyse JSON avec les outils Unix

J’essaie d’parsingr JSON renvoyé par une requête curl, comme ceci:

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]}' 

Ce qui précède divise le JSON en champs, par exemple:

 % ... "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 % ... 

Comment imprimer un champ spécifique (désigné par -vk=text )?

Il existe de nombreux outils spécialement conçus pour manipuler JSON à partir de la ligne de commande, et ils seront beaucoup plus faciles et plus fiables que de le faire avec Awk, comme jq :

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

Vous pouvez également le faire avec des outils qui sont probablement déjà installés sur votre système, comme Python en utilisant le module json , et ainsi éviter toute dépendance supplémentaire, tout en bénéficiant d’un parsingur JSON approprié. Ce qui suit suppose que vous souhaitez utiliser UTF-8, dont le JSON d’origine doit être codé et que les terminaux les plus modernes utilisent également:

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'])" 

Notes historiques

A l’origine, cette réponse recommandait jsawk , qui devrait toujours fonctionner, mais qui est un peu plus difficile à utiliser que jq , et qui dépend de l’installation d’un interpréteur JavaScript autonome, moins courant qu’un interpréteur Python.

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

Cette réponse utilisait également à l’origine l’API Twitter de la question, mais cette API ne fonctionne plus, ce qui rend difficile la copie des exemples à tester, et la nouvelle API Twitter requirejs des clés API. J’ai donc utilisé l’API GitHub peut être utilisé facilement sans clés API. La première réponse à la question initiale serait:

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

Pour extraire rapidement les valeurs d’une clé particulière, j’aime personnellement utiliser “grep -o”, qui ne renvoie que la correspondance de l’expression régulière. Par exemple, pour obtenir le champ “texte” des tweets, quelque chose comme:

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

Cette regex est plus robuste que vous ne le pensez; Par exemple, il convient parfaitement aux chaînes comportant des virgules incorporées et aux guillemets échappés. Je pense qu’avec un peu plus de travail, vous pourriez en faire un qui est réellement garanti pour extraire la valeur, si c’est atomique. (S’il y a une imbrication, une regex ne peut pas le faire bien sûr.)

Et pour nettoyer (en gardant la fuite de la chaîne), vous pouvez utiliser quelque chose comme: | perl -pe 's/"text"://; s/^"//; s/",$//' | perl -pe 's/"text"://; s/^"//; s/",$//' | perl -pe 's/"text"://; s/^"//; s/",$//' . (Je l’ai fait pour cette parsing .)

Pour tous les haineux qui insistent, vous devez utiliser un parsingur JSON réel – oui, c’est essentiel pour l’exactitude, mais

  1. Pour faire une parsing très rapide, comme compter des valeurs pour vérifier les bogues de nettoyage des données ou avoir une idée générale des données, il est plus rapide de bash quelque chose sur la ligne de commande. Ouvrir un éditeur pour écrire un script est source de distraction.
  2. grep -o est des ordres de grandeur plus rapides que la bibliothèque json standard de Python, du moins pour les tweets (~ 2 Ko chacun). Je ne sais pas si c’est juste parce que json est lent (je devrais comparer à yajl parfois); mais en principe, une regex devrait être plus rapide car son état fini et beaucoup plus optimisable, au lieu d’un parsingur qui doit prendre en charge la récursivité et, dans ce cas, dépense beaucoup d’arbres de construction pour les structures qui ne vous intéressent pas. (Si quelqu’un a écrit un transducteur à états finis qui effectuait une parsing JSON correcte (limitée en profondeur), ce serait fantastique! En attendant, nous avons “grep -o”.)

Pour écrire du code maintenable, j’utilise toujours une véritable bibliothèque d’parsing. Je n’ai pas essayé jsawk , mais si cela fonctionne bien, cela répondrait au point n ° 1.

Une dernière solution, plus farfelue: j’ai écrit un script qui utilise Python json et extrait les clés souhaitées dans des colonnes séparées par des tabulations; puis je traverse un wrapper autour de awk qui permet un access nommé aux colonnes. Ici: les scripts json2tsv et tsvawk . Donc, pour cet exemple, ce serait:

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

Cette approche n'adresse pas le numéro 2, est plus inefficace qu'un script Python unique, et elle est un peu fragile: elle force la normalisation des lignes et des tabulations dans les valeurs de chaîne, pour jouer avec la vue du monde awk. Mais cela vous permet de restr sur la ligne de commande, avec plus de précision que grep -o .

Sur la base que certaines des recommandations ici (en particulier dans les commentaires) suggéraient l’utilisation de Python, j’ai été déçu de ne pas trouver d’exemple.

Donc, voici une ligne pour obtenir une valeur unique à partir de certaines données JSON. Cela suppose que vous dirigez les données (depuis quelque part) et que vous devriez donc les utiliser dans un contexte de script.

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

Après MartinR et Boecko en tête:

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

Cela vous donnera une sortie extrêmement conviviale. Très pratique:

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

Vous pouvez simplement télécharger le binary jq pour votre plate – forme et l’exécuter ( chmod +x jq ):

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

Il extrait l’atsortingbut "name" de l’object json.

jq page d’accueil de jq indique que c’est comme sed pour les données JSON.

Utilisez le support JSON de Python au lieu d’utiliser awk!

Quelque chose comme ça:

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

Utiliser Node.js

Si le système est doté d’un noeud , il est possible d’utiliser les indicateurs de script -p print et -e evaulate avec JSON.parse pour extraire toute valeur nécessaire.

Un exemple simple utilisant la chaîne JSON { "foo": "bar" } et en extrayant la valeur de “foo”:

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

Comme nous avons access à cat et à d’autres utilitaires, nous pouvons l’utiliser pour les fichiers:

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

Ou tout autre format tel qu’une URL contenant JSON:

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

Vous avez demandé comment vous tirer dans le pied et je suis ici pour fournir les munitions:

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

Vous pouvez utiliser tr -d '{}' au lieu de sed . Mais les abandonner complètement semble aussi avoir l’effet désiré.

Si vous voulez supprimer les guillemets externes, dirigez le résultat de ce qui précède vers sed 's/\(^"\|"$\)//g'

Je pense que d’autres ont sonné suffisamment d’alarme. Je restrai avec un téléphone portable pour appeler une ambulance. Feu quand prêt.

Utiliser Bash avec Python

Créez une fonction bash dans votre fichier .bash_rc

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

alors

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

Voici la même fonction, mais avec vérification des erreurs.

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

Où $ # -ne 1 s'assure qu'au moins 1 entrée et -t 0 s'assurent que vous redirigez depuis un tube.

La bonne chose à propos de cette implémentation est que vous pouvez accéder aux valeurs json nestedes et obtenir json en retour! =)

Exemple:

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

Si vous voulez être vraiment chic, vous pouvez imprimer les données:

 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" } 

Analyse JSON avec PHP CLI

Sans doute hors sujet, mais puisque la préséance règne, cette question rest incomplète sans une mention de notre PHP fidèle et fidèle, n’est-ce pas?

En utilisant le même exemple JSON, mais permet de l’assigner à une variable pour réduire l’obscurité.

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

Maintenant, pour PHP, utilisez file_get_contents et le stream php: // stdin .

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

ou comme indiqué en utilisant fgets et le stream déjà ouvert à la constante CLI STDIN .

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

nJoy!

TickTick est un parsingur JSON écrit en bash (<250 lignes de code)

Voici l’extrait de l’auteur tiré de son article, Imaginez un monde où Bash prend en charge JSON :

 #!/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 

Version native Bash: fonctionne également bien avec les barres obliques inverses (\) et les guillemets (“)

 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 qui utilise Ruby et http://flori.github.com/json/

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

ou plus concis:

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

Vous pouvez utiliser jshon :

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

Malheureusement, la réponse la plus votée qui utilise grep renvoie la correspondance complète qui n’a pas fonctionné dans mon scénario, mais si vous savez que le format JSON restra constant, vous pouvez utiliser lookbehind et lookahead pour extraire uniquement les valeurs souhaitées.

 # 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 

voici un moyen de le faire avec awk

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

Quelqu’un qui a aussi des fichiers XML, pourrait vouloir regarder mon Xidel . Il s’agit d’un processeur JSONiq sans dépendances . (c.-à-d. qu’il prend également en charge XQuery pour le traitement XML ou JSON)

L’exemple dans la question serait:

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

Ou avec ma propre syntaxe d’extension non standard:

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

Pour une parsing JSON plus complexe, je suggère d’utiliser le module python jsonpath (par Stefan Goessner) –

  1. Installez-le –

sudo easy_install -U jsonpath

  1. Utilise le –

Exemple de fichier.json (extrait de 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 } } } 

Analyser (extraire tous les titres du livre avec le prix <10) -

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

Will sortie -

 Sayings of the Century Moby Dick 

REMARQUE: la ligne de commande ci-dessus n'inclut pas la vérification des erreurs. pour une solution complète avec vérification des erreurs, vous devez créer un petit script python et envelopper le code avec try-except.

Si vous avez php :

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

Par exemple:
nous avons des ressources qui fournissent json avec les codes iso des pays: http://country.io/iso3.json et nous pouvons facilement le voir dans un shell avec curl:

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

mais il ne semble pas très pratique et pas lisible, mieux parsingr json et voir la structure lisible:

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

Ce code imprimera quelque chose comme:

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

Si vous avez des tableaux nesteds, cette sortie sera beaucoup mieux …

J’espère que cela vous sera utile …

Maintenant que Powershell est multi plate-forme, j’ai pensé que je pouvais y aller, car je le trouve assez intuitif et extrêmement simple.

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

ConvertFrom-Json convertit le JSON en object personnalisé Powershell, ce qui vous permet de travailler facilement avec les propriétés de ce point. Si vous ne vouliez que la propriété ‘id’, par exemple, vous feriez simplement ceci:

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

Si vous vouliez appeler le tout depuis Bash, vous devriez l’appeler comme ceci:

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

Bien sûr, il y a une manière pure de Powershell de le faire sans boucler, ce qui serait:

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

Enfin, il y a aussi ‘ConvertTo-Json’ qui convertit tout aussi facilement un object personnalisé en JSON. Voici un exemple:

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

Ce qui produirait un joli JSON comme celui-ci:

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

}

Certes, l’utilisation d’un shell Windows sur Unix est quelque peu sacrilège, mais Powershell est très efficace pour certaines choses, et l’parsing de JSON et XML en fait partie. Ceci la page GitHub pour la version multi-plateforme https://github.com/PowerShell/PowerShell

Vous pouvez essayer quelque chose comme ça –

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

L’parsing JSON est douloureuse dans un script shell. Avec un langage plus approprié, créez un outil qui extrait les atsortingbuts JSON d’une manière compatible avec les conventions de script shell. Vous pouvez utiliser votre nouvel outil pour résoudre le problème de script shell immédiat, puis l’append à votre kit pour des situations futures.

Par exemple, considérez un outil jsonlookup tel que si je dis jsonlookup access token id il retournera l’ identifiant d’ atsortingbut défini dans le jeton d’ atsortingbut défini dans l’atsortingbut access de stdin, qui est probablement les données JSON. Si l’atsortingbut n’existe pas, l’outil ne renvoie rien (état de sortie 1). Si l’parsing échoue, quittez le statut 2 et un message à stderr. Si la recherche réussit, l’outil imprime la valeur de l’atsortingbut.

Ayant créé un outil Unix dans le but précis d’extraire des valeurs JSON, vous pouvez facilement l’utiliser dans des scripts shell:

 access_token=$(curl  | jsonlookup access token id) 

Tout langage fera l’affaire pour l’implémentation de jsonlookup . Voici une version python assez concise:

 #!/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 

Un deux lignes qui utilise le python. Cela fonctionne particulièrement bien si vous écrivez un seul fichier .sh et que vous ne voulez pas dépendre d’un autre fichier .py. Il tire également parti de l’utilisation de tuyaux | . echo "{\"field\": \"value\"}" peut être remplacé par tout ce qui imprime json sur la sortie standard.

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

Ceci est une bonne utilisation pour pythonpy :

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

Ceci est encore une autre réponse hybride bash & python . J’ai posté cette réponse parce que je voulais traiter une sortie JSON plus complexe, mais en réduisant la complexité de mon application bash. Je veux ouvrir l’object JSON suivant depuis http://www.arcgis.com/sharing/rest/info?f=json dans bash :

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

Bien que cette approche augmente la complexité de la fonction Python, l’utilisation de bash devient plus simple:

 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 

La sortie du script ci-dessus est:

J’ai ajouté le support pour les tableaux, vous pouvez donc utiliser .length et, si le source est un tableau de chaînes, vous pouvez utiliser .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 

Quelles sorties:

  • 1
  • [{“scale”: 591657527.591555, “resolution”: 156543.03392800014, “level”: 0}, {“scale”: 295828763.795777, “resolution”: 78271.51696399994, “level”: 1}, {“scale”: 147914381.897889 “: 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 “: 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 ssortingng_regex='"([^"\]|\\.)*"' local number_regex='-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?' local value_regex="${ssortingng_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 . Dans ce cas:

 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