Le maigre
jq -r '(.[0] | keys_unsorted) as $keys | $keys, map([.[ $keys[] ]])[] | @csv'
ou:
jq -r '(.[0] | keys_unsorted) as $keys | ([$keys] + map([.[ $keys[] ]])) [] | @csv'
Les détails
De côté
Décrire les détails est délicat car jq est orienté flux, ce qui signifie qu'il fonctionne sur une séquence de données JSON, plutôt que sur une seule valeur. Le flux JSON d'entrée est converti en un type interne qui est passé à travers les filtres, puis codé dans un flux de sortie à la fin du programme. Le type interne n'est pas modélisé par JSON et n'existe pas en tant que type nommé. Il est plus facile de le démontrer en examinant la sortie d'un index nu ( .[]
) ou de l'opérateur virgule (l'examiner directement pourrait être fait avec un débogueur, mais ce serait en termes de types de données internes de jq, plutôt que de types de données conceptuels derrière JSON) .
$ jq -c '. []' <<< '["a", "b"]'
"une"
"b"
$ jq -cn '"a", "b"'
"une"
"b"
Notez que la sortie n'est pas un tableau (ce qui serait ["a", "b"]
). La sortie compacte (l' -c
option) montre que chaque élément du tableau (ou argument du ,
filtre) devient un objet distinct dans la sortie (chacun est sur une ligne distincte).
Un flux est comme un JSON-seq , mais utilise des nouvelles lignes plutôt que RS comme séparateur de sortie lorsqu'il est encodé. Par conséquent, ce type interne est désigné par le terme générique «séquence» dans cette réponse, «flux» étant réservé pour l'entrée et la sortie codées.
Construire le filtre
Les clés du premier objet peuvent être extraites avec:
.[0] | keys_unsorted
Les clés seront généralement conservées dans leur ordre d'origine, mais la préservation de l'ordre exact n'est pas garantie. Par conséquent, ils devront être utilisés pour indexer les objets pour obtenir les valeurs dans le même ordre. Cela empêchera également les valeurs d'être dans les mauvaises colonnes si certains objets ont un ordre de clé différent.
Pour afficher les clés dans la première ligne et les rendre disponibles pour l'indexation, elles sont stockées dans une variable. L'étape suivante du pipeline fait alors référence à cette variable et utilise l'opérateur virgule pour ajouter l'en-tête au flux de sortie.
(.[0] | keys_unsorted) as $keys | $keys, ...
L'expression après la virgule est un peu compliquée. L'opérateur d'index sur un objet peut prendre une séquence de chaînes (par exemple "name", "value"
), renvoyant une séquence de valeurs de propriété pour ces chaînes. $keys
est un tableau, pas une séquence, []
est donc appliqué pour le convertir en séquence,
$keys[]
qui peut ensuite être passé à .[]
.[ $keys[] ]
Cela produit également une séquence, de sorte que le constructeur de tableau est utilisé pour le convertir en tableau.
[.[ $keys[] ]]
Cette expression doit être appliquée à un seul objet. map()
est utilisé pour l'appliquer à tous les objets du tableau externe:
map([.[ $keys[] ]])
Enfin, pour cette étape, cela est converti en une séquence afin que chaque élément devienne une ligne distincte dans la sortie.
map([.[ $keys[] ]])[]
Pourquoi regrouper la séquence dans un tableau au sein du map
seul pour la dégrouper à l'extérieur? map
produit un tableau; .[ $keys[] ]
produit une séquence. Appliquer map
à la séquence from .[ $keys[] ]
produirait un tableau de séquences de valeurs, mais comme les séquences ne sont pas de type JSON, vous obtenez à la place un tableau aplati contenant toutes les valeurs.
["NSW","AU","state","New South Wales","AB","CA","province","Alberta","ABD","GB","council area","Aberdeenshire","AK","US","state","Alaska"]
Les valeurs de chaque objet doivent être conservées séparément, afin qu'elles deviennent des lignes distinctes dans la sortie finale.
Enfin, la séquence est passée par le @csv
formateur.
Alterner
Les articles peuvent être séparés tardivement plutôt que tôt. Au lieu d'utiliser l'opérateur virgule pour obtenir une séquence (en passant une séquence comme opérande de droite), la séquence d'en-tête ( $keys
) peut être enveloppée dans un tableau et +
utilisée pour ajouter le tableau de valeurs. Celui-ci doit encore être converti en séquence avant d'être transmis à @csv
.
json2csv
est à stackoverflow.com/questions/57242240/…