我试图解析从curl请求返回的JSON,就像这样:
curl 'http://twitter.com/users/username.json' |
sed -e 's/[{}]/''/g' |
awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}'
上面将JSON划分为多个字段,例如:
% ...
"geo_enabled":false
"friends_count":245
"profile_text_color":"000000"
"status":"in_reply_to_screen_name":null
"source":"web"
"truncated":false
"text":"My status"
"favorited":false
% ...
我如何打印一个特定的字段(由-v k=文本表示)?
在shell脚本中解析JSON非常痛苦。使用更合适的语言,创建一个工具,以与shell脚本约定一致的方式提取JSON属性。您可以使用您的新工具来解决当前的shell脚本问题,然后将其添加到您的工具包中以备将来使用。
例如,考虑一个jsonlookup工具,如果我说jsonlookup访问令牌id,它将返回在来自标准输入的属性访问中定义的属性令牌中定义的属性id,这些属性令牌可能是JSON数据。如果该属性不存在,该工具将不返回任何内容(退出状态1)。如果解析失败,则退出状态2并返回标准错误消息。如果查找成功,该工具将打印属性的值。
创建了一个用于精确提取JSON值的Unix工具后,您可以轻松地在shell脚本中使用它:
access_token=$(curl <some horrible crap> | jsonlookup access token id)
任何语言都可以实现jsonlookup。下面是一个相当简洁的Python版本:
#!/usr/bin/python
import sys
import json
try: rep = json.loads(sys.stdin.read())
except:
sys.stderr.write(sys.argv[0] + ": unable to parse JSON from stdin\n")
sys.exit(2)
for key in sys.argv[1:]:
if key not in rep:
sys.exit(1)
rep = rep[key]
print rep
我需要在Bash中一些简短的东西,可以在没有依赖的情况下运行,而不是香草Linux LSB和Mac OS的Python 2.7和3,并处理错误,例如,将报告JSON解析错误和丢失的属性错误,而不会抛出Python异常:
json-extract () {
if [[ "$1" == "" || "$1" == "-h" || "$1" == "-?" || "$1" == "--help" ]] ; then
echo 'Extract top level property value from json document'
echo ' Usage: json-extract <property> [ <file-path> ]'
echo ' Example 1: json-extract status /tmp/response.json'
echo ' Example 2: echo $JSON_STRING | json-extract status'
echo ' Status codes: 0 - success, 1 - json parse error, 2 - property missing'
else
python -c $'import sys, json;\ntry: obj = json.load(open(sys.argv[2])); \nexcept: sys.exit(1)\ntry: print(obj[sys.argv[1]])\nexcept: sys.exit(2)' "$1" "${2:-/dev/stdin}"
fi
}
YAML处理器yq
考虑使用yq进行JSON处理。
yq是一个轻量级、可移植的命令行YAML处理器(JSON是YAML的一个子集)。
语法类似于jq。
输入
{
"name": "Angel",
"address": {
"street": "Stairway to",
"city": "Heaven"
}
}
用法举例1
yq e ` .name ` $FILE
Angel
用法举例二
yq有一个很好的内置特性,可以使JSON和YAML成为grep-able
yq——输出格式道具$FILE
name = Angel
address.street = Stairway to
address.city = Heaven
如果你安装了PHP解释器:
php -r 'var_export(json_decode(`curl http://twitter.com/users/username.json`, 1));'
例如:
我们有一个资源,提供JSON内容与国家的ISO代码:http://country.io/iso3.json,我们可以很容易地看到它在一个shell与curl:
curl http://country.io/iso3.json
但它看起来不是很方便,也不容易读。更好地解析JSON内容并看到可读的结构:
php -r 'var_export(json_decode(`curl http://country.io/iso3.json`, 1));'
这段代码将打印如下内容:
array (
'BD' => 'BGD',
'BE' => 'BEL',
'BF' => 'BFA',
'BG' => 'BGR',
'BA' => 'BIH',
'BB' => 'BRB',
'WF' => 'WLF',
'BL' => 'BLM',
...
如果你有嵌套数组,这个输出看起来会更好…