Analizando JSON con herramientas Unix

Estoy tratando de analizar JSON devuelto de una solicitud curl, así:

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

Lo anterior divide el JSON en campos, por ejemplo:

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

¿Cómo -vk=text un campo específico (indicado por el -vk=text )?

Hay una serie de herramientas diseñadas específicamente para manipular JSON desde la línea de comandos, y será mucho más fácil y más confiable que hacerlo con Awk, como jq :

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

También puede hacerlo con herramientas que probablemente ya estén instaladas en su sistema, como Python utilizando el módulo json , y así evitar cualquier dependencia adicional, al tiempo que tiene el beneficio de un analizador JSON adecuado. A continuación, suponga que desea utilizar UTF-8, en el que debe codificarse el JSON original y es lo que también utilizan los terminales más modernos:

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

Notas históricas

Esta respuesta originalmente recomendaba jsawk , que aún debería funcionar, pero es un poco más engorroso de usar que jq , y depende de que se instale un intérprete de JavaScript independiente que es menos común que un intérprete de Python, por lo que las respuestas anteriores son probablemente preferibles:

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

Esta respuesta también usó originalmente la API de Twitter a partir de la pregunta, pero esa API ya no funciona, por lo que es difícil copiar los ejemplos para probar, y la nueva API de Twitter requiere claves API, así que he cambiado a usar la API GitHub que se puede usar fácilmente sin claves API. La primera respuesta para la pregunta original sería:

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

Para extraer rápidamente los valores de una clave en particular, personalmente me gusta usar “grep -o”, que solo devuelve la coincidencia de la expresión regular. Por ejemplo, para obtener el campo “texto” de los tweets, algo como:

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

Esta expresión regular es más sólida de lo que piensas; por ejemplo, funciona bien con cadenas que tienen comas incrustadas y comillas escapadas dentro de ellas. Creo que con un poco más de trabajo podrías hacer uno que esté realmente garantizado para extraer el valor, si es atómico. (Si tiene anidamiento, entonces una expresión regular no puede hacerlo, por supuesto).

Y para seguir limpiando (aunque manteniendo el escape original de la cuerda) puede usar algo como: | perl -pe 's/"text"://; s/^"//; s/",$//' | perl -pe 's/"text"://; s/^"//; s/",$//' | perl -pe 's/"text"://; s/^"//; s/",$//' . (Hice esto para este análisis ).

Para todos los enemigos que insisten en que se debe usar un analizador JSON real, sí, eso es esencial para la corrección, pero

  1. Para hacer un análisis realmente rápido, como contar valores para verificar los errores de limpieza de datos o obtener una idea general de los datos, golpear algo en la línea de comandos es más rápido. Abrir un editor para escribir un guión es una distracción.
  2. grep -o es órdenes de magnitud más rápido que la biblioteca estándar de Python json , al menos cuando se hace esto para tweets (que son ~ 2 KB cada uno). No estoy seguro si esto es solo porque json es lento (debería compararlo con el yajl alguna vez); pero en principio, una expresión regular debería ser más rápida ya que es un estado finito y mucho más optimizable, en lugar de un analizador sintáctico que debe admitir la recursión, y en este caso, gasta muchos CPU construyendo árboles para estructuras que no te importan. (Si alguien escribiera un transductor de estado finito que hiciera un análisis JSON apropiado (con profundidad limitada), ¡sería fantástico! Mientras tanto tenemos “grep -o”).

Para escribir código mantenible, siempre uso una biblioteca de análisis real. No he probado jsawk , pero si funciona bien, eso sería abordar el punto n. ° 1.

Una última, más extraña, solución: escribí un script que usa Python json y extrae las claves que desea, en columnas separadas por tabuladores; luego canalizo un wrapper alrededor de awk que permite el acceso con nombre a las columnas. Aquí: los scripts json2tsv y tsvawk . Entonces para este ejemplo sería:

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

Este enfoque no aborda el # 2, es más ineficiente que un solo script de Python, y es un poco frágil: fuerza la normalización de nuevas líneas y tabs en valores de cadena, para jugar bien con la vista del mundo de awk / campo delimitado por registros. Pero te permite mantenerte en la línea de comando, con más corrección que grep -o .

Sobre la base de que algunas de las recomendaciones aquí (especialmente en los comentarios) sugirieron el uso de Python, me decepcionó no encontrar un ejemplo.

Entonces, aquí hay un trazador de líneas para obtener un solo valor de algunos datos JSON. Supone que estás conectando los datos (desde algún lugar) y, por lo tanto, debería ser útil en un contexto de scripting.

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

Siguiendo el ejemplo de MartinR y Boecko:

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

Eso le dará una salida amigable extremadamente grep. Muy conveniente:

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

Simplemente puede descargar jq binary para su plataforma y ejecutar ( chmod +x jq ):

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

Extrae el atributo "name" del objeto json.

jq página de inicio de jq dice que es como sed para datos JSON.

¡Utiliza el soporte JSON de Python en lugar de utilizar awk!

Algo como esto:

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

Usando Node.js

Si el sistema tiene un nodo instalado, es posible usar las marcas de comandos -p print y -e evaulate script con JSON.parse para extraer cualquier valor que sea necesario.

Un ejemplo simple usando la cadena JSON { "foo": "bar" } y extrayendo el valor de “foo”:

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

Debido a que tenemos acceso a cat y otras utilidades, podemos usar esto para archivos:

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

O cualquier otro formato, como una URL que contenga JSON:

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

Has preguntado cómo dispararte en el pie y estoy aquí para proporcionarte la munición:

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

Podría usar tr -d '{}' lugar de sed . Pero dejarlos afuera parece tener también el efecto deseado.

Si quiere quitar las cotizaciones externas, canalice el resultado de lo anterior a través de sed 's/\(^"\|"$\)//g'

Creo que otros han sonado suficiente alarma. Estaré esperando con un teléfono celular para llamar a una ambulancia. Fuego cuando esté listo.

Usando Bash con Python

Crea una función bash en tu archivo .bash_rc

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

Entonces

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

Aquí está la misma función, pero con la comprobación de errores.

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

Donde $ # -ne 1 asegura al menos 1 entrada, y -t 0 asegúrese de que está redirigiendo desde un conducto.

Lo bueno de esta implementación es que puedes acceder a los valores json nesteds y obtener json a cambio. =)

Ejemplo:

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

Si quieres ser realmente elegante, podrías imprimir bastante los datos:

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

Analizando JSON con PHP CLI

Posiblemente fuera de tema, pero desde que reina la precedencia, esta pregunta permanece incompleta sin una mención de nuestro confiable y fiel PHP, ¿estoy en lo cierto?

Usando el mismo ejemplo de JSON pero permitiéndole asignarlo a una variable para reducir la oscuridad.

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

Ahora, para bondad de PHP, usando file_get_contents y la envoltura de flujo de php: // stdin .

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

o como se señala usando fgets y el flujo ya abierto en la constante de la CLI STDIN .

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

nJoy!

TickTick es un analizador JSON escrito en bash (<250 líneas de código)

Aquí está el snippit del autor de su artículo, Imagine un mundo donde Bash admite 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 

Versión Native Bash: también funciona bien con barras diagonales inversas (\) y comillas (“)

 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 

Versión que usa Ruby y http://flori.github.com/json/

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

o más concisamente:

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

Puedes usar jshon :

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

Lamentablemente, la respuesta más votada que usa grep devuelve la coincidencia completa que no funcionó en mi escenario, pero si sabe que el formato JSON se mantendrá constante, puede usar lookbehind y lookahead para extraer solo los valores deseados.

 # 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 

aquí hay una forma en que puedes hacerlo con 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 } } }' 

Alguien que también tenga archivos xml, podría querer mirar mi Xidel . Es un cli, procesador JSONiq libre de dependencia . (es decir, también es compatible con XQuery para el procesamiento xml o json)

El ejemplo en la pregunta sería:

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

O con mi propia syntax de extensión no estándar:

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

Para un análisis JSON más complejo, sugiero usar el módulo python jsonpath (de Stefan Goessner) –

  1. Instalarlo –

sudo easy_install -U jsonpath

  1. Úselo –

Ejemplo file.json (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 } } } 

Parse it (extraer todos los títulos de libros con precio <10) -

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

Se producirá -

 Sayings of the Century Moby Dick 

NOTA: La línea de comando anterior no incluye la comprobación de errores. para una solución completa con comprobación de errores, debe crear una secuencia de comandos python pequeña y ajustar el código con try -excepto.

Si tienes php :

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

Por ejemplo:
tenemos recursos que proporcionan json con los códigos de países iso: http://country.io/iso3.json y podemos verlo fácilmente en un shell con curl:

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

pero no parece muy conveniente, y no es legible, mejor analizar json y ver la estructura legible:

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

Este código imprimirá algo como:

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

si tiene matrices anidadas, esta salida se verá mucho mejor …

Espero que esto sea útil …

Ahora que Powershell es multiplataforma, pensé en abrirme camino, ya que creo que es bastante intuitivo y extremadamente simple.

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

ConvertFrom-Json convierte el JSON en un objeto personalizado de Powershell, por lo que puede trabajar fácilmente con las propiedades desde ese momento. Si solo quisieras la propiedad ‘id’ por ejemplo, simplemente harías esto:

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

Si quisieras invocar todo desde Bash, deberías llamarlo así:

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

Por supuesto, hay una forma pura de Powershell para hacerlo sin curl, que sería:

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

Finalmente, también hay ‘ConvertTo-Json’ que convierte un objeto personalizado a JSON con la misma facilidad. Aquí hay un ejemplo:

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

Que produciría un buen JSON como este:

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

}

Es cierto que usar un shell de Windows en Unix es un poco sacrílego, pero Powershell es realmente bueno en algunas cosas, y el análisis de JSON y XML son algunas de ellas. Esta es la página de GitHub para la versión multiplataforma https://github.com/PowerShell/PowerShell

Puedes probar algo como esto:

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

El análisis de JSON es doloroso en un script de shell. Con un lenguaje más apropiado, cree una herramienta que extraiga atributos JSON de una manera consistente con las convenciones de scripts de shell. Puede usar su nueva herramienta para resolver el problema inmediato de scripting de shell y luego agregarlo a su kit para situaciones futuras.

Por ejemplo, considere una herramienta jsonlookup de modo que si digo jsonlookup access token id devolverá el id. De atributo definido dentro del token de atributo definido dentro del atributo access de stdin, que es supuestamente datos JSON. Si el atributo no existe, la herramienta no devuelve nada (estado de salida 1). Si el análisis falla, salga del estado 2 y un mensaje a stderr. Si la búsqueda tiene éxito, la herramienta imprime el valor del atributo.

Después de haber creado una herramienta de Unix para el propósito preciso de extraer valores JSON, puede usarla fácilmente en scripts de shell:

 access_token=$(curl  | jsonlookup access token id) 

Cualquier idioma servirá para la implementación de jsonlookup . Aquí hay una versión bastante concisa de Python:

 #!/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 dos líneas que utiliza python. Funciona especialmente bien si está escribiendo un solo archivo .sh y no desea depender de otro archivo .py. También aprovecha el uso de tubería | . echo "{\"field\": \"value\"}" puede ser reemplazado por cualquier cosa que imprima un json al stdout.

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

Este es un buen caso de uso para pythonpy :

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

Esta es otra respuesta híbrida de bash y python . Publiqué esta respuesta porque quería procesar una salida JSON más compleja, pero reduciendo la complejidad de mi aplicación bash. Quiero abrir el siguiente objeto JSON de http://www.arcgis.com/sharing/rest/info?f=json en bash :

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

Si bien este enfoque aumenta la complejidad en la función de Python, el uso de bash se vuelve más 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 

El resultado del script anterior es:

.length soporte para matrices, por lo que puede usar .length y, si la fuente es una matriz de cadenas, puede usar .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 

Qué salidas:

  • 1
  • [{“escala”: 591657527.591555, “resolución”: 156543.03392800014, “nivel”: 0}, {“escala”: 295828763.795777, “resolución”: 78271.51696399994, “nivel”: 1}, {“escala”: 147914381.897889, “resolución “: 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 . En este caso:

 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 

Ejemplos de uso:

 $ 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