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


当前回答

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

其他回答

这里有一种使用AWK的方法:

curl -sL 'http://twitter.com/users/username.json' | awk -F"," -v k="text" '{
    gsub(/{|}/,"")
    for(i=1;i<=NF;i++){
        if ( $i ~ k ){
            print $i
        }
    }
}'

你可以下载jq二进制文件到你的平台,然后运行(chmod +x jq):

$ curl 'https://twitter.com/users/username.json' | ./jq -r '.name'

它从json对象中提取“name”属性。

jq主页说它类似于JSON数据的sed。

在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

这是另一个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

这是使用大多数发行版上可用的标准Unix工具。它也适用于反斜杠(\)和引号(")。

警告:这并不能接近jq的功能,并且只能用于非常简单的JSON对象。这是在无法安装其他工具的情况下尝试回答最初的问题。

function parse_json()
{
    echo $1 | \
    sed -e 's/[{}]/''/g' | \
    sed -e 's/", "/'\",\"'/g' | \
    sed -e 's/" ,"/'\",\"'/g' | \
    sed -e 's/" , "/'\",\"'/g' | \
    sed -e 's/","/'\"---SEPERATOR---\"'/g' | \
    awk -F=':' -v RS='---SEPERATOR---' "\$1~/\"$2\"/ {print}" | \
    sed -e "s/\"$2\"://" | \
    tr -d "\n\t" | \
    sed -e 's/\\"/"/g' | \
    sed -e 's/\\\\/\\/g' | \
    sed -e 's/^[ \t]*//g' | \
    sed -e 's/^"//'  -e 's/"$//'
}


parse_json '{"username":"john, doe","email":"john@doe.com"}' username
parse_json '{"username":"john doe","email":"john@doe.com"}' email

--- outputs ---

john, doe
johh@doe.com