我试图解析从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.
有一个有趣的工具在现有的答案中还没有涉及到,那就是使用用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。
你有多种选择。
您可以使用trdsql[1]来解析和转换JSON/CSV输入。以你为榜样;
trdsql "select attr1,attr2 from sample.json"
你也可以像SQL一样使用where子句。输出在CSV, JSON等。非常方便的工具。
根据我的经验,trdsql在处理属性嵌套值时有点问题,所以我在适当的时候使用qp[2]找到了一个解决方案。
cat sample.json | qp 'select attr1, attr2.detail.name where attr3=10'
注意这里没有FROM。
为了查看结果,您可以使用超快速命令行json查看器工具jless来查看输出[3]。
Clickhouse来了个新人。您可以从[4]中看到它的功能。
https://github.com/noborus/trdsql
https://jless.io
https://github.com/f5io/qp
https://clickhouse.com/blog/extracting-converting-querying-local-files-with-sql-clickhouse-local