我试图解析从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=文本表示)?


当前回答

yum install PHP -cli后使用PHP:

php -r " foreach(json_decode(file_get_contents('http://a.com/a.json'), true) as \$key => \$value) echo \$key.'='.\$value.\"\n\" ; "

其他回答

下面是shell书呆子使用POSIX shell(带local)和egrep的答案:JSON.sh, 4.7 KB。

这个东西有很多测试用例,所以它应该是正确的。它也是可管道的。它用于Bash的包管理器bpkg。

使用node . js

如果系统安装了Node.js,则可以在JSON中使用-p print和-e evaluate脚本标志。解析以提取所需的任何值。

一个简单的例子,使用JSON字符串{"foo": "bar"}并取出"foo"的值:

node -pe 'JSON.parse(process.argv[1]).foo' '{ "foo": "bar" }'

输出:

bar

因为我们可以访问cat和其他实用程序,我们可以对文件使用这个:

node -pe 'JSON.parse(process.argv[1]).foo' "$(cat foobar.json)"

输出:

bar

或包含JSON的URL等任何其他格式:

node -pe 'JSON.parse(process.argv[1]).name' "$(curl -s https://api.github.com/users/trevorsenior)"

输出:

Trevor Senior

这是pythonpy的一个很好的用例:

curl 'http://twitter.com/users/username.json' | py 'json.load(sys.stdin)["name"]'

有XML文件的人可能想看看我的Xidel。它是一个命令行界面,无依赖的JSONiq处理器。(也就是说,它还支持XQuery进行XML或JSON处理。)

问题中的例子是:

 xidel -e 'json("http://twitter.com/users/username.json")("name")'

或者用我自己的非标准扩展语法:

 xidel -e 'json("http://twitter.com/users/username.json").name'

在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