Lorsque l’on souhaite convertir des données brutes en JSON avec jq on se retrouve souvent confronté un souci dès la première étape et comme débutant on est obligé de multiplier les appels à jq.
Limiter les appels à « jq »
On va considérer le fichier texte suivant :
a
b
c
Que l’on va simuler à l’aide du code suivant :
printf 'a\nb\nc'
Le code JSON attendu étant le suivant :
[
"a",
"b",
"c"
]
La première idée est d’utiliser les drapeaux --raw-input
et --slurp
comme suit :
printf 'a\nb\nc' | jq --raw-input --slurp
Mais on se retrouve avec le résultat suivant :
"a\nb\nc"
Cependant en utilisant deux appels successifs, on a bien ce que l’on attendait :
printf 'a\nb\nc' | jq --raw-input | jq --slurp
Transforme d’abord les lignes en chaîne JSON, puis construit un tableau de chaîne.
[
"a",
"b",
"c"
]
Pour faire la même chose en une seule commande jq, voici comment faire :
printf 'a\nb\nc' | jq --raw-input --null-input '[inputs]'
Le drapeau --raw-input
transforme chaque ligne du fichier en chaîne JSON,
Le drapeau -null-input
indique de ne pas traiter l’entrée standard (puisqu’on va utiliser la commande inputs
pour prendre en compte cette entrée).
La commande inputs
retourne l’entrée standard (une liste de chaîne JSON) et comme elle est entourée par un début et une fin de tableau : cette liste est mise dans un tableau.
[
"a",
"b",
"c"
]
Exemple concret
Considérons le texte suivant :
a=A
b=B
c=C
Que l’on souhaite convertir en JSON comme suit :
{
"a": "A",
"b": "B",
"c": "C"
}
Voici deux exemples de code qui produisent cette sortie :
printf 'a=A\nb=B\nc=C' |
jq --raw-input --null-input '
[inputs] |
map( . | split("=") | { (.[0]) : .[1] } ) |
reduce .[] as $x ({}; . + $x)
'
On peut éviter le map
ainsi :
printf 'a=A\nb=B\nc=C' |
jq --raw-input --null-input '
[
inputs | split("=") | { (.[0]): .[1] }
] |
reduce .[] as $x ({}; . + $x)
'
Liens
ᦿ