在shell中我有一个要求,其中我必须阅读以下格式的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]}
但这还不够。任何人都可以帮我这个吗?
答案 0 :(得分:77)
答案 1 :(得分:12)
$ 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
提供其他人real world examples以及json:select() doc。
答案 2 :(得分:5)
同样使用Bash regexp。应该能够抢夺任何键/值对。
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
可以调整正则表达式以匹配多个空格/制表符或换行符。如果值已嵌入"
,则无效。这是一个例证。最好使用一些“工业”解析器:)
答案 3 :(得分:1)
这是一种粗略的方法:将JSON转换为bash
变量到eval
。
这仅适用于:
嗯,是的,它使用PERL来完成这项工作,感谢CPAN,但它足够小,可以直接包含在脚本中,因此调试快速简便:
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"]}')"
(不幸的是,以下是仅限链接的解决方案,因为C代码很远 这里复制的时间太长了。)
对于那些不喜欢上述解决方案的人,
现在有C program json2sh
哪个(希望安全地)将JSON转换为shell变量。
与perl
代码段相比,它可以处理任何JSON,
只要它形成良好。
注意事项:
json2sh
未经过多次测试。json2sh
可能会创建以shellshock模式() {
我写了json2sh
以便能够使用Shell后处理.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
转储.bson
文件,使记录成为JSON数组
END0
- 标记,否则您会看到类似END1
的内容。END
- 标记,否则将显示空.bson
个文件。bsons2json
将一堆.bson
个文件作为对象转储,其中bson2json
的输出由文件名索引。然后由json2sh
对其进行后处理,以便您可以使用grep
/ source
/ eval
/等。你需要什么,将值带入shell。
这样您就可以在shell级别快速处理MongoDB转储的内容,而无需先将其导入MongoDB。