シェルでは、次の形式のJSON応答を読み取る必要があるという要件があります。
{ "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" } ] }
ここでは、「Body」プロパティ値のみに関係します。私は次のようないくつかの失敗した試みをしました:
jsawk -a 'return this.Body'
または
awk -v k="Body" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}
しかし、それでは十分ではありませんでした。誰でもこれで私を助けることができますか?
$ cat /tmp/so.json | underscore select '.Messages .Body'
["172.16.1.42|/home/480/1234/5-12-2013/1234.toSort"]
次のようなJavascript CLIツールを使用できます。
name
のすべてのaddons
子を選択します。
underscore select ".addons > .name"
underscore-cli
は、他の 実世界の例 と json:select()doc を提供します。
同様に、Bash正規表現を使用します。任意のキー/値ペアを奪うことができるものとします。
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
正規表現は、複数のスペース/タブまたは改行に一致するように調整できます。値に"
が埋め込まれていると機能しません。これは実例です。いくつかの「産業用」パーサーを使用する方が良い:)
粗雑な方法は次のとおりです。JSONをbash
変数からeval
変数に変換します。
これは以下に対してのみ機能します:
ええ、そうです、CPANのおかげで、Perlを使用してこの仕事をしていますが、スクリプトに直接含めるには十分に小さいため、すばやく簡単にデバッグできます。
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($_));'
}
eval "$(json2bash <<<'{"a":["b","c"]}')"
のように使用します
ただし、十分にテストされていません。更新、警告、その他の例については、私の Gist を参照してください。
(残念なことに、Cコードは長すぎてここで複製できないため、以下はリンクのみのソリューションです。)
上記のソリューションが気に入らないすべての人のために、JSONをシェル変数に(できれば安全に)変換する Cプログラムjson2sh があります。 Perl
スニペットとは対照的に、整形式である限り、任意のJSONを処理できます。
警告:
json2sh
はあまりテストされていません。json2sh
は、Shellshockパターンで始まる変数を作成できます() {
json2sh
をシェルで後処理できるように.bson
を作成しました。
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 | ..
説明:
bson2json
は、レコードがJSON配列になるように.bson
ファイルをダンプしますEND0
- Markerが適用され、そうでない場合はEND1
のようなものが表示されます。END
- Markerが必要です。そうでない場合、空の.bson
ファイルは表示されません。bsons2json
は、.bson
ファイルの束をオブジェクトとしてダンプします。ここで、bson2json
の出力はファイル名でインデックス付けされます。これはjson2sh
によって後処理され、grep
/source
/eval
/etcを使用できます。シェルに値を取り込むために必要なもの。
この方法により、MongoDBに最初にインポートする必要なく、シェルレベルでMongoDBダンプの内容をすばやく処理できます。