阅读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转换成bashvariables来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 。