¿Cómo formatear una cadena JSON como una tabla usando jq?
Acaba de empezar con Bash scripting y se topó con jq para trabajar con JSON.
Necesito transformar una cadena JSON como la siguiente en una tabla para la salida en el terminal.
[{
"name": "George",
"id": 12,
"email": "[email protected]"
}, {
"name": "Jack",
"id": 18,
"email": "[email protected]"
}, {
"name": "Joe",
"id": 19,
"email": "[email protected]"
}]
Lo que quiero mostrar en el terminal:
ID Name
=================
12 George
18 Jack
19 Joe
Observe cómo no quiero mostrar la propiedad de correo electrónico para cada fila, por lo que el comando jq debería incluir algún filtrado. Lo siguiente me da una lista simple de nombres e identificaciones:
list=$(echo "$data" | jq -r '.[] | .name, .id')
printf "$list"
El problema con eso es que no puedo mostrarlo como tabla. Sé que jq tiene algunas opciones de formato, pero no tan buenas como las opciones que tengo cuando uso printf
. Creo que quiero obtener estos valores en una matriz que luego puedo bucle a través de mí mismo para hacer el formato...? Las cosas que probé me dan resultados variables, pero nunca lo que realmente quiero.
¿Puede alguien señalarme en la dirección correcta?
3 answers
¿Por qué no algo como :
echo '[{
"name": "George",
"id": 12,
"email": "[email protected]"
}, {
"name": "Jack",
"id": 18,
"email": "[email protected]"
}, {
"name": "Joe",
"id": 19,
"email": "[email protected]"
}]' | jq -r '.[] | "\(.id)\t\(.name)"'
Salida
12 George
18 Jack
19 Joe
Editar 1: Para el formato de grano fino use herramientas como awk
echo '[{
"name": "George",
"id": 12,
"email": "[email protected]"
}, {
"name": "Jack",
"id": 18,
"email": "[email protected]"
}, {
"name": "Joe",
"id": 19,
"email": "[email protected]"
}]' | jq -r '.[] | [.id, .name] | @csv' | awk -v FS="," 'BEGIN{print "ID\tName";print "============"}{printf "%s\t%s%s",$1,$2,ORS}'
ID Name
============
12 "George"
18 "Jack"
19 "Joe"
Edit 2 : En respuesta a
No hay manera de que pueda obtener una variable que contenga una matriz recta de jq?
¿Por qué no?
Un ejemplo involucrado( de hecho modificado del suyo ) donde el correo electrónico se cambia a una matriz demuestra esto
echo '[{
"name": "George",
"id": 20,
"email": [ "[email protected]" , "[email protected]" ]
}, {
"name": "Jack",
"id": 18,
"email": [ "[email protected]" , "[email protected]" ]
}, {
"name": "Joe",
"id": 19,
"email": [ "[email protected]" ]
}]' | jq -r '.[] | .email'
Salida
[
"[email protected]",
"[email protected]"
]
[
"[email protected]",
"[email protected]"
]
[
"[email protected]"
]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 09:06:20
Usar el filtro @tsv
tiene mucho que recomendarlo, principalmente porque maneja numerosos "casos de borde"de una manera estándar:
.[] | [.id, .name] | @tsv
La adición de los encabezados se puede hacer de la siguiente manera:
jq -r '["ID","NAME"], ["--","------"], (.[] | [.id, .name]) | @tsv'
El resultado:
ID NAME
-- ------
12 George
18 Jack
19 Joe
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 11:50:23
Si los valores no contienen espacios, esto podría ser útil:
read -r -a data <<<'name1 value1 name2 value2'
echo "name value"
echo "=========="
for ((i=0; i<${#data[@]}; i+=2)); do
echo ${data[$i]} ${data[$((i+1))]}
done
Salida
name value
==========
name1 value1
name2 value2
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 11:54:37