Tengo un archivo JSON members.json
como se muestra a continuación.
{
"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"
}
}
]
}
}
Quiero analizarlo usando el bash
script para obtener solo la lista de campos memberId
.
El resultado esperado es:
memberIds
-----------
0x7b93910446f91928e23e1043dfdf5bcf
0x7b93910446f91928e23e1043dfdf5bcG
Intenté agregar el siguiente 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'"]';
}
Y luego llamó:
$ cat members.json | getJsonVal "memberId"
Pero arroja:
Traceback (most recent call last):
File "<string>", line 1, in <module>
KeyError: 'memberId'
python
, y nobash
, es lo que está usando para analizar json. Por ejemplo, ese error es ciertamente un error de Python, no un error bash.python
, no significa que su objetivo sea usarpython
Respuestas:
Si usarías:
Puede inspeccionar la estructura del dictonario anidado
obj
y ver que su línea original debería leer:a ese elemento "memberId". De esta manera, puedes mantener Python como un oneliner.
Si hay varios elementos en el elemento "hits" anidado, puede hacer algo como:
La solución de Chris Down es mejor para encontrar un valor único para claves (únicas) en cualquier nivel.
Con mi segundo ejemplo que imprime múltiples valores, estás alcanzando los límites de lo que deberías probar con un solo revestimiento, en ese momento veo pocas razones por las que hacer la mitad del procesamiento en bash, y pasaría a una solución completa de Python .
fuente
Otra forma de hacer esto en bash es usar jshon . Aquí hay una solución a su problema usando
jshon
:Las
-e
opciones extraen valores de json. El-a
itera sobre la matriz y-u
decodifica la cadena final.fuente
Bueno, su clave claramente no está en la raíz del objeto. Intenta algo como esto:
Esto tiene el beneficio de no solo inyectar sintaxis en Python, lo que podría causar la rotura (o peor, la ejecución de código arbitrario).
Entonces puedes llamarlo así:
fuente
Otra alternativa es jq :
fuente
Prueba esto:
Si ya tienes
pretty printed
json, ¿por qué no lo hacesgrep
?Siempre puede obtener un formato bastante impreso con simplejson python
grep
.Usar volcados:
A partir de entonces, simplemente
grep
resulte con el patrón 'memberId'.Para ser completamente preciso:
Uso:
fuente
Siguiendo este hilo , usaría json.tool en python:
python -m json.tool members.json | awk -F'"' '/memberId/{print $4}'
fuente
Usando deepdiff no necesita saber las claves exactas:
fuente
Aquí hay una solución bash.
find_members.sh
agregue la siguiente línea al archivo + guardar
chmod +x find_members.sh
Ahora ejecútelo:
fuente