Analisando JSON com ferramentas Unix

Estou tentando analisar o JSON retornado de uma solicitação de onda, assim:

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

O acima divide o JSON em campos, por exemplo:

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

Como imprimo um campo específico (denotado por -vk=text )?

Existem várias ferramentas especificamente projetadas para o propósito de manipular o JSON a partir da linha de comando, e serão muito mais fáceis e confiáveis ​​do que fazê-lo com o Awk, como o jq :

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

Você também pode fazer isso com ferramentas que provavelmente já estão instaladas em seu sistema, como Python usando o módulo json , e assim evitar quaisquer dependencies extras, enquanto ainda tem o benefício de um analisador JSON adequado. O seguinte assume que você deseja usar o UTF-8, no qual o JSON original deve ser codificado e é o que os terminais mais modernos também usam:

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 resposta originalmente recomendou o jsawk , que ainda deve funcionar, mas é um pouco mais trabalhoso do que o jq , e depende de um intérprete JavaScript autônomo instalado que é menos comum que um interpretador Python, então as respostas acima são provavelmente preferíveis:

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

Essa resposta também usou originalmente a API do Twitter da pergunta, mas essa API não funciona mais, dificultando a cópia dos exemplos para testar, e a nova API do Twitter exige chaves de API, então mudei para usar a API do GitHub, que pode ser usado facilmente sem chaves de API. A primeira resposta para a pergunta original seria:

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

Para extrair rapidamente os valores de uma chave específica, eu pessoalmente gosto de usar “grep -o”, que retorna apenas a correspondência da regex. Por exemplo, para obter o campo “texto” dos tweets, algo como:

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

Esse regex é mais robusto do que você imagina; por exemplo, lida bem com strings tendo vírgulas embutidas e citações com escape dentro delas. Eu acho que com um pouco mais de trabalho você pode fazer um que realmente garanta a extração do valor, se for atômico. (Se tiver aninhamento, então um regex não pode fazer isso é claro).

E para limpar ainda mais (embora mantendo o escape original da string) você pode usar algo como: | perl -pe 's/"text"://; s/^"//; s/",$//' | perl -pe 's/"text"://; s/^"//; s/",$//' | perl -pe 's/"text"://; s/^"//; s/",$//' . (Eu fiz isso para esta análise ).

Para todos os inimigos que insistem que você deve usar um analisador JSON real – sim, isso é essencial para correção, mas

  1. Para fazer uma análise realmente rápida, como contar valores para checar erros de limpeza de dados ou ter uma noção geral dos dados, fazer algo na linha de comando é mais rápido. Abrir um editor para escrever um script é uma distração.
  2. grep -o é uma ordem de magnitude mais rápida que a biblioteca json padrão do Python, pelo menos ao fazer isso para tweets (que são ~ 2 KB cada). Eu não tenho certeza se isso é apenas porque json é lento (eu deveria comparar com yajl algum dia); mas, em princípio, um regex deve ser mais rápido, uma vez que é um estado finito e muito mais otimizável, em vez de um analisador que tem de suportar recursion e, neste caso, gasta muitas trees de construção de CPU para estruturas que você não se importa. (Se alguém escrevesse um transdutor de estado finito que fizesse uma análise de JSON adequada (com profundidade limitada), isso seria fantástico! Enquanto isso, temos “grep -o”.)

Para escrever código de manutenção, eu sempre uso uma biblioteca de análise real. Eu não tentei jsawk , mas se funcionar bem, isso resolveria o ponto # 1.

Uma última solução, mais louca: eu escrevi um script que usa Python json e extrai as chaves que você quer, em colunas separadas por tabulações; então eu canalizo através de um wrapper em torno do awk que permite o access nomeado às colunas. Aqui: os scripts json2tsv e tsvawk . Então, para este exemplo, seria:

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

Essa abordagem não é a 2, é mais ineficiente do que um script Python, e é um pouco frágil: força a normalização de novas linhas e abas em valores de strings, para brincar com a visão de mundo do campo / registro de awk. Mas permite que você fique na linha de comando, com mais correção do que grep -o .

Na base de que algumas das recomendações aqui (especialmente nos comentários) sugeriram o uso do Python, fiquei desapontado por não encontrar um exemplo.

Então, aqui está um forro para obter um único valor de alguns dados JSON. Ele pressupõe que você esteja inserindo os dados (de algum lugar) e, portanto, deve ser útil em um contexto de script.

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

Seguindo o exemplo de MartinR e Boecko:

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

Isso lhe dará uma saída extremamente amigável para o grep. Muito conveniente:

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

Você pode simplesmente baixar o jq binary para sua plataforma e executar ( chmod +x jq ):

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

Ele extrai o atributo "name" do object json.

jq homepage diz que é como sed para dados JSON.

Use o suporte a JSON do Python em vez de usar o awk!

Algo assim:

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

Usando o Node.js

Se o sistema tiver o nó instalado, é possível usar os sinalizadores de script -p print e -e JSON.parse com JSON.parse para extrair qualquer valor que seja necessário.

Um exemplo simples usando a string JSON { "foo": "bar" } e retirando o valor de “foo”:

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

Como temos access ao cat e outros utilitários, podemos usar isso para arquivos:

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

Ou qualquer outro formato, como um URL que contenha JSON:

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

Você perguntou como se atirar no pé e eu estou aqui para fornecer a munição:

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

Você poderia usar tr -d '{}' vez de sed . Mas deixá-los completamente fora parece ter o efeito desejado também.

Se você quiser despir as aspas externas, canalize o resultado do acima através de sed 's/\(^"\|"$\)//g'

Eu acho que outros soaram alarme suficiente. Eu ficarei parado com um celular para chamar uma ambulância. Dispare quando pronto.

Usando o Bash com o Python

Crie uma function bash no seu arquivo .bash_rc

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

Então

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

Aqui está a mesma function, mas com a verificação de erros.

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

Onde $ # -ne 1 certifica-se de pelo menos 1 input, e -t 0 verifique se você está redirecionando de um pipe.

O legal dessa implementação é que você pode acessar valores json nesteds e obter json em retorno! =)

Exemplo:

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

Se você quer ser realmente chique, pode imprimir os dados:

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

Analisando JSON com PHP CLI

Indiscutivelmente off topic, mas desde que a precedência reina esta questão permanece incompleta sem uma menção do nosso fiel e fiel PHP, estou certo?

Usando o mesmo exemplo JSON, mas vamos atribuí-lo a uma variável para reduzir a obscuridade.

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

Agora, para o bem do PHP, usando file_get_contents e o wrapper de stream php: // stdin .

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

ou como apontado usando fgets e o stream já aberto na constante CLI STDIN .

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

nJoy!

TickTick é um analisador JSON escrito em bash (<250 linhas de código)

Aqui está o snippit do autor de seu artigo, Imagine um mundo onde o Bash suporta 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 

Versão nativa do Bash: Também funciona bem com barras invertidas (\) e aspas (“)

 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 

Versão que usa Ruby e http://flori.github.com/json/

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

ou mais concisa:

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

Você pode usar o jshon :

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

Infelizmente, a resposta mais votada que usa grep retorna a correspondência completa que não funcionou no meu cenário, mas se você souber que o formato JSON permanecerá constante, poderá usar lookbehind e lookahead para extrair apenas os valores desejados.

 # 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 

aqui está uma maneira de fazer isso com o 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 } } }' 

Alguém que também tem arquivos xml, pode querer olhar para o meu Xidel . É um processador JSONiq livre de dependência e cli . (ou seja, também suporta XQuery para processamento xml ou json)

O exemplo na pergunta seria:

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

Ou com a minha própria syntax de extensão não padrão:

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

Para uma análise JSON mais complexa, sugiro usar o módulo python jsonpath (por Stefan Goessner) –

  1. Instale-o –

sudo easy_install -U jsonpath

  1. Use-o –

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

Analise (extraia todos os títulos de livros com preço <10) -

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

Vai sair -

 Sayings of the Century Moby Dick 

NOTA: A linha de comando acima não inclui a verificação de erros. para uma solução completa com verificação de erros, você deve criar um pequeno script python e encapsular o código com try-except.

Se você tem php :

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

Por exemplo:
temos resources que fornecem códigos iso de json com países: http://country.io/iso3.json e podemos facilmente vê-lo em um shell com curl:

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

mas não parece muito conveniente, e não legível, melhor analisar json e ver a estrutura legível:

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

Este código irá imprimir algo como:

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

se você tiver matrizes aninhadas, essa saída ficará muito melhor …

Espero que isso ajude …

Agora que o Powershell é uma plataforma cruzada, pensei em lançar seu caminho até lá, pois acho que é bastante intuitivo e extremamente simples.

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

ConvertFrom-Json converte o JSON em um object personalizado do Powershell, para que você possa trabalhar facilmente com as propriedades desse ponto em diante. Se você quisesse a propriedade ‘id’ por exemplo, você só faria isso:

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

Se você quisesse invocar a coisa toda dentro do Bash, então você teria que chamar assim:

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

Claro que há uma maneira Powershell pura de fazer isso sem enrolar, o que seria:

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

Finalmente, há também ‘ConvertTo-Json’, que converte um object personalizado para JSON com a mesma facilidade. Aqui está um exemplo:

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

O que produziria um bom JSON assim:

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

}

Evidentemente, usar um shell do Windows no Unix é um pouco sacrilégio, mas o Powershell é realmente bom em algumas coisas, e a análise de JSON e XML são algumas delas. Esta é a página do GitHub para a versão de plataforma cruzada https://github.com/PowerShell/PowerShell

Você pode tentar algo assim –

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

Analisar JSON é doloroso em um script de shell. Com uma linguagem mais apropriada, crie uma ferramenta que extraia os atributos JSON de maneira consistente com as convenções de script de shell. Você pode usar sua nova ferramenta para resolver o problema imediato de script de shell e adicioná-lo ao seu kit para situações futuras.

Por exemplo, considere uma ferramenta jsonlookup que, se eu disser jsonlookup access token id , retornará o id de atributo definido dentro do token de atributo definido no access de atributo de stdin, que é presumivelmente dados JSON. Se o atributo não existir, a ferramenta não retornará nada (status de saída 1). Se a análise falhar, saia do status 2 e uma mensagem para stderr. Se a pesquisa for bem-sucedida, a ferramenta imprimirá o valor do atributo.

Tendo criado uma ferramenta unix para o propósito preciso de extrair valores JSON, você pode facilmente usá-la em scripts de shell:

 access_token=$(curl  | jsonlookup access token id) 

Qualquer idioma servirá para a implementação do jsonlookup . Aqui está uma versão de python bastante concisa:

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

Um dois-liner que usa python. Isso funciona particularmente bem se você estiver escrevendo um único arquivo .sh e não quiser depender de outro arquivo .py. Também aproveita o uso do tubo | . echo "{\"field\": \"value\"}" pode ser substituído por qualquer coisa que imprima um json para o stdout.

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

Este é um bom uso para pythonpy :

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

Esta é mais uma resposta híbrida bash & python . Eu postei esta resposta porque queria processar uma saída JSON mais complexa, mas reduzindo a complexidade do meu aplicativo bash. Eu quero quebrar o seguinte object JSON de http://www.arcgis.com/sharing/rest/info?f=json no bash :

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

Embora essa abordagem aumente a complexidade na function Python, o uso do bash se torna mais simples:

 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 

A saída do script acima é:

Eu adicionei suporte para arrays, então você pode usar .length e, se a fonte for um array de strings, você pode 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 

Quais saídas:

  • 1
  • [{“scale”: 591657527.591555, “resolution”: 156543.03392800014, “level”: 0}, {“scale”: 295828763.795777, “resolução”: 78271.51696399994, “level”: 1}, {“scale”: 147914381.897889, “resolução “: 39135.75848200009,” level “: 2}, {” scale “: 73957190.948944,” resolução “: 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 . Nesse 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 

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