El delgado
jq -r '(.[0] | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv'
o:
jq -r '(.[0] | keys_unsorted) as $keys | ([$keys] + map([.[ $keys[] ]])) [] | @csv'
Los detalles
Aparte
Describir los detalles es complicado porque jq está orientado a la transmisión, lo que significa que opera en una secuencia de datos JSON, en lugar de un valor único. El flujo JSON de entrada se convierte a algún tipo interno que se pasa a través de los filtros y luego se codifica en un flujo de salida al final del programa. El tipo interno no está modelado por JSON y no existe como un tipo con nombre. Se demuestra más fácilmente examinando la salida de un índice simple ( .[]
) o el operador de coma (examinarlo directamente podría hacerse con un depurador, pero eso sería en términos de los tipos de datos internos de jq, en lugar de los tipos de datos conceptuales detrás de JSON) .
$ jq -c '. []' <<< '["a", "b"]'
"una"
"si"
$ jq -cn '"a", "b"'
"una"
"si"
Tenga en cuenta que la salida no es una matriz (lo que sería ["a", "b"]
). La salida compacta (la -c
opción) muestra que cada elemento de la matriz (o argumento del ,
filtro) se convierte en un objeto separado en la salida (cada uno está en una línea separada).
Una secuencia es como un JSON-seq , pero utiliza nuevas líneas en lugar de RS como separador de salida cuando se codifica. En consecuencia, este tipo interno se conoce con el término genérico "secuencia" en esta respuesta, con "flujo" reservado para la entrada y salida codificadas.
Construyendo el filtro
Las claves del primer objeto se pueden extraer con:
.[0] | keys_unsorted
Por lo general, las claves se mantendrán en su orden original, pero no se garantiza la conservación del orden exacto. En consecuencia, deberán usarse para indexar los objetos y obtener los valores en el mismo orden. Esto también evitará que los valores estén en las columnas incorrectas si algunos objetos tienen un orden de clave diferente.
Para generar las claves como la primera fila y hacerlas disponibles para indexación, se almacenan en una variable. La siguiente etapa de la canalización hace referencia a esta variable y usa el operador de coma para anteponer el encabezado al flujo de salida.
(.[0] | keys_unsorted) as $keys | $keys, ...
La expresión después de la coma es un poco complicada. El operador de índice de un objeto puede tomar una secuencia de cadenas (por ejemplo "name", "value"
), devolviendo una secuencia de valores de propiedad para esas cadenas. $keys
es una matriz, no una secuencia, por lo que []
se aplica para convertirla en una secuencia,
$keys[]
que luego se puede pasar a .[]
.[ $keys[] ]
Esto también produce una secuencia, por lo que el constructor de la matriz se usa para convertirla en una matriz.
[.[ $keys[] ]]
Esta expresión debe aplicarse a un solo objeto. map()
se usa para aplicarlo a todos los objetos de la matriz externa:
map([.[ $keys[] ]])
Por último, para esta etapa, esto se convierte en una secuencia para que cada elemento se convierta en una fila separada en la salida.
map([.[ $keys[] ]])[]
¿Por qué agrupar la secuencia en una matriz dentro de la map
única para desagregarla fuera? map
produce una matriz; .[ $keys[] ]
produce una secuencia. Aplicar map
a la secuencia de .[ $keys[] ]
produciría una matriz de secuencias de valores, pero dado que las secuencias no son de tipo JSON, en su lugar obtiene una matriz plana que contiene todos los valores.
["NSW","AU","state","New South Wales","AB","CA","province","Alberta","ABD","GB","council area","Aberdeenshire","AK","US","state","Alaska"]
Los valores de cada objeto deben mantenerse separados, de modo que se conviertan en filas separadas en la salida final.
Finalmente, la secuencia se pasa a través del @csv
formateador.
Alterno
Los elementos se pueden separar más tarde que temprano. En lugar de usar el operador de coma para obtener una secuencia (pasando una secuencia como el operando derecho), la secuencia de encabezado ( $keys
) se puede envolver en una matriz y +
usarse para agregar la matriz de valores. Esto aún debe convertirse en una secuencia antes de pasarlo @csv
.
json2csv
está en stackoverflow.com/questions/57242240/…