阅读shell脚本中的JSON数据
在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" } ] }
在这里,我只关心“身体”的财产价值。 我做了一些不成功的尝试,如:
jsawk -a 'return this.Body'
要么
awk -vk="Body" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}
但是这还不够。 谁能帮我这个?
有jq
在命令行上parsingjson:
jq '.Body'
访问jq: https ://stedolan.github.io/jq/
TL;博士
$ cat /tmp/so.json | underscore select '.Messages .Body' ["172.16.1.42|/home/480/1234/5-12-2013/1234.toSort"]
Javascript CLI工具
您可以使用Javascript CLI工具
- 下划线 :
- json:select() :用于JSON的类CSSselect器。
例
select一个addons
所有name
孩子:
underscore select ".addons > .name"
underscore-cli
提供了其他真实世界的例子以及json:select()doc 。
同样使用Bash正则expression式。 应该能够抢夺任何键/值对。
key="Body" re="\"($key)\": \"([^\"]*)\"" while read -rl; do if [[ $l =~ $re ]]; then name="${BASH_REMATCH[1]}" value="${BASH_REMATCH[2]}" echo "$name=$value" else echo "No match" fi done
正则expression式可以调整为匹配多个空格/制表符或换行符。 如果价值已经embedded,这将是不行的"
这是一个例子,最好使用一些”工业“parsing器:)
这是一个简单的方法:将JSON转换成bash
variables来eval
它们。
这只适用于:
- 不包含嵌套数组的JSON,和
- JSON来自可靠的来源(否则它可能会混淆你的shell脚本,也许它甚至可能会损害你的系统, 你已经被警告过了 )
那么,是的,它使用PERL来完成这项工作,这要归功于CPAN,但是它足够小,可以直接包含在脚本中,因此debugging起来很快,很容易:
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"]}')"
虽然没有经过严格testing。 更新,警告和更多的例子见我的GIST 。