1
votes

Construire un Json dans Bash avec deux tableaux

J'ai en fait 2 tableaux dans bash qui contiennent des valeurs de chaîne. Quelque chose comme ça:

declare -a test_array
declare -a test_array2
test_array=(apple orange lemon)
test_array2=(DANGER OK WARNING)
echo ${test_array[0]}

echo '['
printf '{"CVEC": "%s", "LVL" : "%s"},\n' "${test_array[@]}, ${test_array2[@]}" | sed '$s/,$//'
echo ']'

Display 

[
{"CVEC": "apple", "LVL" : "orange"},
{"CVEC": "lemon, DANGER", "LVL" : "OK"},
{"CVEC": "WARNING", "LVL" : ""}
]

Je voudrais créer un json avec 2 attributs, quelque chose comme ça si possible

{
   "results":[
      {
         "nom":"Kevin",
         "status":"OK"
      },
      {
         "nom":"Paul",
         "status":"Danger"
      }
   ]
}

J'ai beaucoup lu en parlant de JQ que j'utilise déjà pour mes tableaux, mais personne ne parle de quelque chose comme je veux :(

Un de mes tests (qui ne répond pas à ce que je voudrais):

XXX


9 commentaires

La raison d'utiliser jq est qu'il garantit un JSON valide quelles que soient les valeurs stockées dans les tableaux. Une approche pure bash vous oblige à faire tout l'examen des valeurs pour vous assurer que les choses qui doivent être échappées sont gérées correctement.


Oui bien sûr, mais je n'ai rien trouvé pour bash et build de json qui répondent à ceci:


C'est parce que bash n'a pas de moyen intégré pour traiter en toute sécurité la production de JSON.


Il semble que vous recherchez une fonction zip. par exemple. github.com/stedolan/jq/issues/609


Non, pas du tout ce dont j'ai besoin


Similaire à: stackoverflow.com/q/41045659/10971581 , stackoverflow.com/q/30721317/10971581 et stackoverflow.com/q/17403498/10971581


Aussi: rosettacode.org/wiki/…


@jhnc: semble ressource très obsolète


@jhnc zip fonctionnerait si vous aviez déjà des tableaux JSON; le problème est de convertir en toute sécurité un tableau bash en tableau JSON en premier lieu.


3 Réponses :


0
votes

Une manière:

{"results":[{"nom":"Kevin","status":"OK"},{"nom":"Paul","status":"DANGER"}]}

produit

paste <(printf "%s\n" "${Array1[@]}") <(printf "%s\n" "${Array2[@]}") |
    jq -nRc '{ results: [inputs] | map(split("\t") | { nom: .[0], status: .[1] }) }'

Cela suppose que les éléments de vos tableaux ne contiennent ni tabulations ni retours à la ligne. Il utilise paste pour générer des paires d'éléments de tableau correspondants, séparés par des tabulations, une paire par ligne, puis utilise jq pour créer la sortie JSON à partir de cela.


0 commentaires

0
votes

Si l'objectif est de s'en tenir à une solution non jq - et que les commentaires de Chepner sur la nécessité de valider les entrées du tableau ne sont pas un problème pour cette situation - une idée serait de parcourir les indices du tableau.

Données de test:

{"CVEC": "apple", "LVL" : "DANGER"},
{"CVEC": "orange", "LVL" : "OK"},
{"CVEC": "lemon", "LVL" : "WARNING"}

Une simple boucle à travers les indices (0,1,2):

sfx=','                                                   # default printf suffix is a comma

for (( i=0 ; i<${#test_array[@]} ; i++ ))
do
    (( ${i} == ( ${#test_array[@]} - 1 ) )) && sfx=''     # clear suffix for last pass through loop

    printf '{"CVEC": "%s", "LVL" : "%s"}%s\n' "${test_array[${i}]}" "${test_array2[${i}]}" "${sfx}"
done

Ce qui génère les éléments suivants:

$ declare -a test_array=(apple orange lemon)
$ typeset -p test_array
declare -a test_array=([0]="apple" [1]="orange" [2]="lemon")

$ declare -a test_array2=(DANGER OK WARNING)
$ typeset -p test_array2
declare -a test_array2=([0]="DANGER" [1]="OK" [2]="WARNING")


0 commentaires

1
votes

Utilisation d'un moteur de template : outil de ligne de commande Template :: Toolkit de perl : tpage : Fichiers

en-tête:

cpan -i Template::Toolkit

pied de page:

apt install libtemplate-perl

file.tpl (modèle) :

$ jq . file.json
{
  "results": [
    {
      "nom": "Kevin",
      "status": "OK"
    },
    {
      "nom": "Paul",
      "status": "danger"
    }
  ]
}

Script Bash

#!/bin/bash

arr1=( Kevin Paul  )
arr2=( OK danger )

{
    cat header
    for i in "${!arr1[@]}"; do
        ((i==${#arr1[@]}-1)) && sep='' || sep=','
        tpage --define x1="${arr1[i]}" \
              --define x2="${arr2[i]}" \
              --define sep=$sep file.tpl
    done
    cat footer
} | tee file.json

Validation

    {
        "nom": "[% x1 %]",
        "status": "[% x2 %]"
    }[% sep %]

Package

Pour debian et debian comme:

   ]
}

Via CPAN:

{
   "results":[

Check http://www.template-toolkit.org/docs/tools/tpage.html a>


0 commentaires