Lire les données json dans le script shell [dupliquer]

cette question a déjà une réponse ici:

  • Parsing JSON avec des outils Unix 34 réponses

En shell, j'ai une exigence où j'ai à lire la réponse JSON qui est dans le format suivant:

 { "Messages": [ { "Body": "172.16.1.42|/home/480/1234/5-12-2013/1234.toSort", "ReceiptHandle": "uUk89DYFzt1VAHtMW2iz0VSiDcGHY+H6WtTgcTSgBiFbpFUg5lythf+wQdWluzCoBziie8BiS2GFQVoRjQQfOx3R5jUASxDz7SmoCI5bNPJkWqU8ola+OYBIYNuCP1fYweKl1BOFUF+o2g7xLSIEkrdvLDAhYvHzfPb4QNgOSuN1JGG1GcZehvW3Q/9jq3vjYVIFz3Ho7blCUuWYhGFrpsBn5HWoRYE5VF5Bxc/zO6dPT0n4wRAd3hUEqF3WWeTMlWyTJp1KoMyX7Z8IXH4hKURGjdBQ0PwlSDF2cBYkBUA=", "MD5OfBody": "53e90dc3fa8afa3452c671080569642e", "MessageId": "e93e9238-f9f8-4bf4-bf5b-9a0cae8a0ebc" } ] }

ici Je ne suis concerné que par la valeur de la propriété du "corps". J'ai fait quelques tentatives infructueuses comme:

 jsawk -a 'return this.Body' 

ou

 awk -v k="Body" '{n=split("151920920",a,","); for (i=1; i<=n; i++) print a[i]} 

mais cela ne suffisait pas. Quelqu'un peut-il m'aider?

46
demandé sur dreftymac 2013-12-10 11:14:57

4 réponses

Il y a jq pour le parsing json sur la ligne de commande:

 jq '.Body'

visitez ceci pour jq: https://stedolan.github.io/jq /

72
répondu user1305398 2017-06-23 13:46:02

tl; dr

$ cat /tmp/so.json | underscore select '.Messages .Body' 
["172.16.1.42|/home/480/1234/5-12-2013/1234.toSort"]

Javascript CLI tools

vous pouvez utiliser les outils Javascript CLI comme

exemple

Sélectionner tout name enfants d'un addons :

underscore select ".addons > .name"

Le underscore-cli en fournir d'autres des exemples du monde réel ainsi que le json:select() doc .

12
répondu Édouard Lopez 2013-12-10 08:43:38

de la Même façon avec Bash regexp. Doit pouvoir saisir n'importe quelle paire de clés/valeurs.

key="Body"
re="\"($key)\": \"([^\"]*)\""

while read -r l; do
    if [[ $l =~ $re ]]; then
        name="${BASH_REMATCH[1]}"
        value="${BASH_REMATCH[2]}"
        echo "$name=$value"
    else
        echo "No match"
    fi
done

L'expression régulière peut être accordée pour correspondre à plusieurs espaces/onglets ou newline(s). Ne fonctionnerait pas si value a intégré " . Ceci est une illustration. Mieux utiliser un analyseur "industriel":)

5
répondu Mindaugas Kubilius 2013-12-10 08:28:34

Voici une façon rudimentaire de le faire: transformer JSON en bash variables à eval eux.

cela ne fonctionne que pour:

  • JSON qui ne contient pas de tableaux imbriqués, et
  • JSON à partir de sources dignes de confiance (sinon il risque de perturber votre script shell, peut-être, il peut même être en mesure de nuire à votre système, Vous avez été averti )

Well, oui, il utilise PERL pour faire ce travail, grâce au CPAN, mais il est suffisamment petit pour être inclus directement dans un script et donc rapide et facile à déboguer:

json2bash() {
perl -MJSON -0777 -n -E 'sub J {
my ($p,$v) = @_; my $r = ref $v;
if ($r eq "HASH") { J("${p}_$_", $v->{$_}) for keys %$v; }
elsif ($r eq "ARRAY") { $n = 0; J("$p"."[".$n++."]", $_) foreach @$v; }
else { $v =~ '"s/'/'\\''/g"'; $p =~ s/^([^[]*)\[([0-9]*)\](.+)$/\[\]/;
$p =~ tr/-/_/; $p =~ tr/A-Za-z0-9_[]//cd; say "$p='\''$v'\'';"; }
}; J("json", decode_json($_));'
}

utilisez-le comme eval "$(json2bash <<<'{"a":["b","c"]}')"

pas très testé, cependant. Mises à jour, avertissements et autres exemples voir mon GIST .

mise à Jour

(malheureusement, suivre est une solution de lien seulement, comme le code C est loin trop long pour dupliquer ici.)

Pour tous ceux qui n'aiment pas la solution ci-dessus, Il ya maintenant un C Programme json2sh qui (espérons-le en toute sécurité) convertit JSON en variables shell. Contrairement à l'extrait perl , il est capable de traiter n'importe quel JSON, tant qu'il est bien formé.

mises en garde:

  • json2sh n'a pas été testé beaucoup.
  • json2sh peut créer variables, qui commencent par le schéma de shellshock () {

j'ai écrit json2sh pour pouvoir post-traiter .bson avec Shell:

bson2json()
{
printf '[';
{ bsondump ""; echo "\"END$?\""; } | sed '/^{/s/$/,/';
echo ']';
};

bsons2json()
{
printf '{';
c='';
for a;
do
  printf '%s"%q":' "$c" "$a";
  c=',';
  bson2json "$a";
done;
echo '}';
};

bsons2json */*.bson | json2sh | ..

expliquée:

  • bson2json dumps un .bson fichier tel, que les enregistrements deviennent un tableau JSON
    • si tout fonctionne bien, un marqueur END0 est appliqué, sinon vous verrez quelque chose comme END1 .
    • le END - marqueur est nécessaire, sinon les fichiers .bson vides n'apparaîtraient pas.
  • bsons2json renverse un tas de fichiers .bson comme un objet, où la sortie de bson2json est indexée par le nom du fichier.

ce qui est alors post-traité par json2sh , de sorte que vous pouvez utiliser grep / source / eval /etc. ce dont vous avez besoin, à porter les valeurs dans la coque.

de cette façon, vous pouvez traiter rapidement le contenu D'un dump MongoDB au niveau de l'interpréteur de commandes, sans avoir besoin de l'importer dans MongoDB en premier.

1
répondu Tino 2018-03-22 10:40:01