Eu tenho um arquivo JSON members.json
como abaixo.
{
"took": 670,
"timed_out": false,
"_shards": {
"total": 8,
"successful": 8,
"failed": 0
},
"hits": {
"total": 74,
"max_score": 1,
"hits": [
{
"_index": "2000_270_0",
"_type": "Medical",
"_id": "02:17447847049147026174478:174159",
"_score": 1,
"_source": {
"memberId": "0x7b93910446f91928e23e1043dfdf5bcf",
"memberFirstName": "Uri",
"memberMiddleName": "Prayag",
"memberLastName": "Dubofsky"
}
},
{
"_index": "2000_270_0",
"_type": "Medical",
"_id": "02:17447847049147026174478:174159",
"_score": 1,
"_source": {
"memberId": "0x7b93910446f91928e23e1043dfdf5bcG",
"memberFirstName": "Uri",
"memberMiddleName": "Prayag",
"memberLastName": "Dubofsky"
}
}
]
}
}
Eu quero analisá-lo usando bash
script obter apenas a lista de campos memberId
.
A saída esperada é:
memberIds
-----------
0x7b93910446f91928e23e1043dfdf5bcf
0x7b93910446f91928e23e1043dfdf5bcG
Tentei adicionar o seguinte código bash + python a .bashrc
:
function getJsonVal() {
if [ \( $# -ne 1 \) -o \( -t 0 \) ]; then
echo "Usage: getJsonVal 'key' < /tmp/file";
echo " -- or -- ";
echo " cat /tmp/input | getJsonVal 'key'";
return;
fi;
cat | python -c 'import json,sys;obj=json.load(sys.stdin);print obj["'$1'"]';
}
E então chamado:
$ cat members.json | getJsonVal "memberId"
Mas joga:
Traceback (most recent call last):
File "<string>", line 1, in <module>
KeyError: 'memberId'
python
, pois , e nãobash
, é o que você está usando para analisar o json. Por exemplo, esse erro é certamente um erro de python, não um erro de bash.python
, não significa que seu objetivo é usarpython
Respostas:
Se você usaria:
você pode inspecionar a estrutura do dictonary aninhado
obj
e ver que sua linha original deve ler:para o elemento "memberId". Dessa forma, você pode manter o Python como um oneliner.
Se houver vários elementos no elemento "hits" aninhado, você poderá fazer algo como:
A solução de Chris Down é melhor para encontrar um valor único para chaves (exclusivas) em qualquer nível.
No meu segundo exemplo, que imprime vários valores, você está atingindo os limites do que deve tentar com um único liner; nesse ponto, vejo poucas razões para fazer metade do processamento no bash e iria para uma solução completa em Python .
fonte
Outra maneira de fazer isso no bash é usando jshon . Aqui está uma solução para o seu problema usando
jshon
:As
-e
opções extraem valores do json. Ele-a
itera sobre a matriz e-u
decodifica a sequência final.fonte
Bem, sua chave claramente não está na raiz do objeto. Tente algo como isto:
Isso tem o benefício de não apenas injetar sintaxe no Python, o que pode causar interrupção (ou pior, execução arbitrária de código).
Você pode chamá-lo assim:
fonte
Outra alternativa é jq :
fonte
Tente o seguinte:
Se você já tem
pretty printed
json, por que não fazgrep
isso?Você sempre pode obter um formato bastante impresso com o simplejson python
grep
.Use dumps:
Depois disso, basta
grep
resultar com o padrão 'memberId'.Para ser completamente preciso:
Uso:
fonte
Após esta discussão, eu usaria o json.tool em python:
python -m json.tool members.json | awk -F'"' '/memberId/{print $4}'
fonte
Usando o deepdiff, você não precisa saber as chaves exatas:
fonte
Aqui está uma solução bash.
find_members.sh
adicione a seguinte linha ao arquivo + salve
chmod +x find_members.sh
Agora execute-o:
fonte