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


当前回答

对于更复杂的JSON解析,我建议使用Python jsonpath模块(Stefan Goessner) -

Install it - sudo easy_install -U jsonpath Use it - Example file.json (from http://goessner.net/articles/JsonPath) - { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } } Parse it (extract all book titles with price < 10) - cat file.json | python -c "import sys, json, jsonpath; print '\n'.join(jsonpath.jsonpath(json.load(sys.stdin), 'store.book[?(@.price < 10)].title'))" Will output - Sayings of the Century Moby Dick Note: The above command line does not include error checking. For a full solution with error checking, you should create a small Python script, and wrap the code with try-except.

其他回答

这是另一个Bash和Python混合的答案。我发布了这个答案,因为我想处理更复杂的JSON输出,但是,降低了我的bash应用程序的复杂性。我想在Bash中从http://www.arcgis.com/sharing/rest/info?f=json打开以下JSON对象:

{
  "owningSystemUrl": "http://www.arcgis.com",
  "authInfo": {
    "tokenServicesUrl": "https://www.arcgis.com/sharing/rest/generateToken",
    "isTokenBasedSecurity": true
  }
}

在下面的示例中,我创建了自己的jq实现,并利用Python取消引用。你会注意到,一旦我们将Python对象从json导入到Python字典中,我们就可以使用Python语法来导航字典。要浏览上面的内容,语法是:

数据 数据[“增强”] 数据[“authInfo”][“tokenServicesUrl”]

通过在Bash中使用魔法,我们省略了数据,只提供数据右侧的Python文本,即。

jq [真实信息] [实用信息][tokenServicesUrl]

注意,在没有参数的情况下,jq充当JSON修饰符。有了形参,我们可以使用Python语法从字典中提取任何我们想要的东西,包括导航子字典和数组元素。

下面是Bash Python混合函数:

#!/bin/bash -xe

jq_py() {
  cat <<EOF
import json, sys
data = json.load( sys.stdin )
print( json.dumps( data$1, indent = 4 ) )
EOF
}

jq() {
  python -c "$( jq_py "$1" )"
}

unquote_py() {
  cat <<EOF
import json,sys
print( json.load( sys.stdin ) )
EOF
}

unquote() {
  python -c "$( unquote_py )"
}

下面是Bash Python函数的使用示例:

curl http://www.arcgis.com/sharing/rest/info?f=json | tee arcgis.json
# {"owningSystemUrl":"https://www.arcgis.com","authInfo":{"tokenServicesUrl":"https://www.arcgis.com/sharing/rest/generateToken","isTokenBasedSecurity":true}}

cat arcgis.json | jq
# {
#     "owningSystemUrl": "https://www.arcgis.com",
#     "authInfo": {
#         "tokenServicesUrl": "https://www.arcgis.com/sharing/rest/generateToken",
#         "isTokenBasedSecurity": true
#     }
# }

cat arcgis.json | jq '[ "authInfo" ]'
# {
#     "tokenServicesUrl": "https://www.arcgis.com/sharing/rest/generateToken",
#     "isTokenBasedSecurity": true
# }

cat arcgis.json | jq '[ "authInfo" ][ "tokenServicesUrl" ]'
# "https://www.arcgis.com/sharing/rest/generateToken"

cat arcgis.json | jq '[ "authInfo" ][ "tokenServicesUrl" ]' | unquote
# https://www.arcgis.com/sharing/rest/generateToken

如果pip在系统中可用,则:

$ pip install json-query

用法示例:

$ curl -s http://0/file.json | json-query
{
    "key":"value"    
}

$ curl -s http://0/file.json | json-query my.key
value

$ curl -s http://0/file.json | json-query my.keys.
key_1
key_2
key_3

$ curl -s http://0/file.json | json-query my.keys.2
value_2

使用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

有一种更简单的方法可以从JSON字符串中获取属性。使用包。Json文件作为一个例子,试试这个:

#!/usr/bin/env bash
my_val="$(json=$(<package.json) node -pe "JSON.parse(process.env.json)['version']")"

我们使用的是过程。env,因为这会将文件的内容作为字符串放入Node.js,而不会有恶意内容逃脱引用并被解析为代码的风险。

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

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