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


当前回答

使用Python的JSON支持,而不是使用AWK!

就像这样:

curl -s http://twitter.com/users/username.json | \
    python -c "import json,sys;obj=json.load(sys.stdin);print(obj['name']);"

macOS v12.3 (Monterey)删除了/usr/bin/python,因此对于macOS v12.3及更高版本,我们必须使用/usr/bin/python3。

curl -s http://twitter.com/users/username.json | \
    python3 -c "import json,sys;obj=json.load(sys.stdin);print(obj['name']);"

其他回答

如果你安装了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',
  ...

如果你有嵌套数组,这个输出看起来会更好…

在martinr和Boecko的带领下:

curl -s 'http://twitter.com/users/username.json' | python -mjson.tool

这将为您提供一个非常适合grep的输出。非常方便:

curl -s 'http://twitter.com/users/username.json' | python -mjson.tool | grep my_key

有一个有趣的工具在现有的答案中还没有涉及到,那就是使用用Go编写的gron,它的口号是Make JSON可greppable!这正是它所做的。

所以从本质上讲,gron将JSON分解为离散的赋值,查看它的绝对“路径”。与jq等其他工具相比,它的主要优点是允许在不知道要搜索的记录是如何嵌套的情况下搜索值,而不会破坏原始的JSON结构

例如,我想从下面的链接搜索'twitter_username'字段,我只是这样做

% gron 'https://api.github.com/users/lambda' | fgrep 'twitter_username'
json.twitter_username = "unlambda";
% gron 'https://api.github.com/users/lambda' | fgrep 'twitter_username' | gron -u
{
  "twitter_username": "unlambda"
}

就这么简单。请注意gron -u (ungron的缩写)如何从搜索路径重新构造JSON。使用fgrep只是为了将搜索过滤到所需的路径,而不是让搜索表达式作为正则表达式计算,而是作为固定字符串(本质上是grep -F)

另一个搜索字符串以查看记录在嵌套结构中的位置的示例

% echo '{"foo":{"bar":{"zoo":{"moo":"fine"}}}}' | gron | fgrep "fine"
json.foo.bar.zoo.moo = "fine";

它还通过-s命令行标志支持JSON流,在这里您可以连续地对输入流进行gron以获得匹配的记录。此外,gron具有零运行时依赖性。你可以下载Linux、Mac、Windows或FreeBSD的二进制文件并运行它。

更多的用法示例和行程可以在官方Github页面-高级用法中找到

至于为什么可以使用gron而不是其他JSON解析工具,请参阅项目页面的作者注释。

为什么我不应该直接使用jq?

Jq非常棒,比gron强大得多,但这种强大带来了复杂性。Gron的目标是使您更容易使用您已经知道的工具,如grep和sed。

使用Python的JSON支持,而不是使用AWK!

就像这样:

curl -s http://twitter.com/users/username.json | \
    python -c "import json,sys;obj=json.load(sys.stdin);print(obj['name']);"

macOS v12.3 (Monterey)删除了/usr/bin/python,因此对于macOS v12.3及更高版本,我们必须使用/usr/bin/python3。

curl -s http://twitter.com/users/username.json | \
    python3 -c "import json,sys;obj=json.load(sys.stdin);print(obj['name']);"

既然PowerShell是跨平台的,我想我就把它扔到那里,因为我发现它相当直观和非常简单。

curl -s 'https://api.github.com/users/lambda' | ConvertFrom-Json

ConvertFrom-Json将JSON转换为PowerShell自定义对象,这样您就可以轻松地使用这些属性。例如,如果你只想要'id'属性,你只需要这样做:

curl -s 'https://api.github.com/users/lambda' | ConvertFrom-Json | select -ExpandProperty id

如果你想从Bash内部调用整个东西,那么你必须像这样调用它:

powershell 'curl -s "https://api.github.com/users/lambda" | ConvertFrom-Json'

当然,有一个纯粹的PowerShell方法来做它没有卷曲,这将是:

Invoke-WebRequest 'https://api.github.com/users/lambda' | select -ExpandProperty Content | ConvertFrom-Json

最后,还有ConvertTo-Json,它可以很容易地将自定义对象转换为JSON。这里有一个例子:

(New-Object PsObject -Property @{ Name = "Tester"; SomeList = @('one','two','three')}) | ConvertTo-Json

它会生成这样的JSON:

{
"Name":  "Tester",
"SomeList":  [
                 "one",
                 "two",
                 "three"
             ]

}

诚然,在Unix上使用Windows shell有点亵渎神明,但PowerShell确实擅长某些事情,解析JSON和XML就是其中之一。这是跨平台版本PowerShell的GitHub页面