我试图解析从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=文本表示)?
我需要在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
}
不幸的是,使用grep的得票最多的答案返回完整的匹配,这在我的场景中不起作用,但如果您知道JSON格式将保持不变,您可以使用向后和向前查找来提取所需的值。
# echo '{"TotalPages":33,"FooBar":"he\"llo","anotherValue":100}' | grep -Po '(?<="FooBar":")(.*?)(?=",)'
he\"llo
# echo '{"TotalPages":33,"FooBar":"he\"llo","anotherValue":100}' | grep -Po '(?<="TotalPages":)(.*?)(?=,)'
33
# echo '{"TotalPages":33,"FooBar":"he\"llo","anotherValue":100}' | grep -Po '(?<="anotherValue":)(.*?)(?=})'
100
这是使用大多数发行版上可用的标准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