Dans Shell, je suis obligé de lire la réponse JSON au 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é "Body". J'ai fait des tentatives infructueuses comme:
jsawk -a 'return this.Body'
ou
awk -v k="Body" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}
Mais cela n'a pas suffi. Est-ce que quelqu'un peut m'aider avec ça?
Il y a jq
pour analyser json sur la ligne de commande:
jq '.Body'
Visitez ceci pour jq: https://stedolan.github.io/jq/
$ cat /tmp/so.json | underscore select '.Messages .Body'
["172.16.1.42|/home/480/1234/5-12-2013/1234.toSort"]
Vous pouvez utiliser des outils CLI Javascript tels que
Sélectionnez tous les name
enfants d'un addons
:
underscore select ".addons > .name"
Le underscore-cli
fournit d'autres exemples du monde réel ainsi que le json: select () doc .
De même en utilisant Bash regexp. Doit pouvoir attraper n'importe quelle paire clé/valeur.
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 ajustée pour correspondre à plusieurs espaces/onglets ou nouvelle (s) ligne (s). Ne fonctionnerait pas si la valeur avait incorporé "
. Ceci est une illustration. Mieux vaut utiliser un analyseur "industriel" :)
Voici un moyen simple de le faire: Transformez JSON en variables bash
en eval
.
Cela ne fonctionne que pour:
Eh bien, oui, il utilise Perl pour effectuer ce travail, grâce à CPAN, mais il est suffisamment petit pour être inclus directement dans un script et est 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]*)\](.+)$/$1$3\[$2\]/;
$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 lourdement testé, cependant. Mises à jour, avertissements et autres exemples, voir mon Gist .
(Malheureusement, la solution suivante est un lien uniquement, car le code C est beaucoup trop long pour être dupliqué ici.)
Pour tous ceux qui n'aiment pas la solution ci-dessus, il existe maintenant un programme C 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 fichier JSON, tant qu'il est bien formé.
Mises en garde:
json2sh
n'a pas été beaucoup testé.json2sh
peut créer des variables qui commencent par le motif Shellshock () {
J'ai écrit json2sh
pour pouvoir post-traiter .bson
avec Shell:
bson2json()
{
printf '[';
{ bsondump "$1"; echo "\"END$?\""; } | sed '/^{/s/$/,/';
echo ']';
};
bsons2json()
{
printf '{';
c='';
for a;
do
printf '%s"%q":' "$c" "$a";
c=',';
bson2json "$a";
done;
echo '}';
};
bsons2json */*.bson | json2sh | ..
A expliqué:
bson2json
sauvegarde un fichier .bson
de sorte que les enregistrements deviennent un tableau JSON END0
- est appliqué. Sinon, vous verrez quelque chose comme END1
.END
- est nécessaire, sinon les fichiers .bson
vides ne s'afficheraient pas.bsons2json
dump un tas de fichiers .bson
sous forme d'objet, où la sortie de bson2json
est indexée par le nom du fichier.Ceci est ensuite traité par json2sh
, de sorte que vous pouvez utiliser grep
/source
/eval
/etc. ce dont vous avez besoin pour apporter les valeurs dans Shell.
De cette façon, vous pouvez traiter rapidement le contenu d'un dump MongoDB au niveau du shell, sans avoir à l'importer au préalable dans MongoDB.