虽然我可能正在诊断事件的根本原因,确定它影响了多少用户,或者为了评估最近代码更改的性能和吞吐量影响而提取时序日志,但我的工具保持不变:{{1 }},grep
,awk
,sed
,tr
,uniq
,sort
,zcat
,tail
,head
和join
。为了将它们粘合在一起,Unix为我们提供了管道,对于更高级的过滤,我们有split
。如果这些都让我失望,那么总是xargs
。
这些工具非常适合处理CSV文件,制表符分隔文件,具有可预测行格式的日志文件或具有逗号分隔键值对的文件。换句话说,每行都没有上下文的文件。
我最近需要浏览千兆字节的XML来构建用户的直方图。使用我的工具这很容易,但对于更复杂的查询,正常方法会中断。假设我的文件包含以下内容:
perl -e
让我们说我想要生成一个从用户到<foo user="me">
<baz key="zoidberg" value="squid" />
<baz key="leela" value="cyclops" />
<baz key="fry" value="rube" />
</foo>
每<baz>
个平均数的映射。逐行处理不再是一种选择:我需要知道我正在检查哪个用户<foo>
,所以我知道要更新的平均值。完成这项任务的任何类型的Unix一行都可能是不可理解的。
幸运的是,在XML-land中,我们有很多精彩的技术,如XPath,XQuery和XSLT来帮助我们。
以前,我已经习惯使用精彩的<foo>
Perl模块来完成上面的查询,但在找到TextMate Plugin that could run an XPath expression against my current window后,我停止编写一次性Perl脚本来查询XML。我刚刚发现了XMLStarlet正在安装的内容,因为我输入了这个,并且我期待将来使用它。
所以这引出了我的问题:JSON有没有这样的工具?一些调查任务要求我对JSON文件进行类似的查询只是时间问题,并且没有像XPath和XSLT这样的工具,这样的任务将会困难得多。如果我有一堆看起来像这样的JSON:
XML::XPath
想找到每个人的平均电话号码,我可以用XPath做这样的事情:
{
"firstName": "Bender",
"lastName": "Robot",
"age": 200,
"address": {
"streetAddress": "123",
"city": "New York",
"state": "NY",
"postalCode": "1729"
},
"phoneNumber": [
{ "type": "home", "number": "666 555-1234" },
{ "type": "fax", "number": "666 555-4567" }
]
}
我注意到越来越多的数据序列化正在使用JSON完成,因此在将来分析大型数据转储时,这样的处理工具将至关重要。 JSON的语言库非常强大,编写脚本以进行这种处理非常容易,但真正让人们玩数据shell工具是必需的。
答案 0 :(得分:51)
我刚刚发现了这个:
http://stedolan.github.com/jq/
“jq是一个轻量级且灵活的命令行JSON处理器。”
2014年更新:
@ user456584提到:
还有'json'命令(例如'jsontool')。我倾向于喜欢它而不是jq。很UNIX-y。这是该项目的链接:github.com/trentm/json -
在http://github.com/trentm/json的json
自述文件中有一长串相似的内容
- jq :http://stedolan.github.io/jq/
- json:选择:http://jsonselect.org/
- jsonpipe :https://github.com/dvxhouse/jsonpipe
- json-command :https://github.com/zpoley/json-command
- JSONPath :http://goessner.net/articles/JsonPath/,http://code.google.com/p/jsonpath/wiki/Javascript
- jsawk :https://github.com/micha/jsawk
- jshon :http://kmkeen.com/jshon/
- json2 :https://github.com/vi/json2
- fx :https://github.com/antonmedv/fx
答案 1 :(得分:7)
我创建了一个专门用于命令行JSON操作的模块:
https://github.com/ddopson/underscore-cli
它可以让你轻松地做强大的事情:
cat earthporn.json | underscore select '.data .title'
# [ 'Fjaðrárgljúfur canyon, Iceland [OC] [683x1024]',
# 'New town, Edinburgh, Scotland [4320 x 3240]',
# 'Sunrise in Bryce Canyon, UT [1120x700] [OC]',
# ...
# 'Kariega Game Reserve, South Africa [3584x2688]',
# 'Valle de la Luna, Chile [OS] [1024x683]',
# 'Frosted trees after a snowstorm in Laax, Switzerland [OC] [1072x712]' ]
cat earthporn.json | underscore select '.data .title' | underscore count
# 25
underscore map --data '[1, 2, 3, 4]' 'value+1'
# prints: [ 2, 3, 4, 5 ]
underscore map --data '{"a": [1, 4], "b": [2, 8]}' '_.max(value)'
# [ 4, 8 ]
echo '{"foo":1, "bar":2}' | underscore map -q 'console.log("key = ", key)'
# key = foo
# key = bar
underscore pluck --data "[{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}]" name
# [ 'moe', 'larry', 'curly' ]
underscore keys --data '{name : "larry", age : 50}'
# [ 'name', 'age' ]
underscore reduce --data '[1, 2, 3, 4]' 'total+value'
# 10
它有一个非常好的命令行帮助系统,非常灵活。经过充分测试,可随时使用;但是,我仍然在构建一些功能,比如输入/输出格式的替代品,以及我的模板处理工具中的合并(参见TODO.md)。如果您有任何功能请求,请对此帖子发表评论或在github中添加问题。我设计了一个非常广泛的功能集,但我很乐意优先考虑社区成员所需的功能。
答案 2 :(得分:5)
您可以做的一种方法是将其转换为XML。以下使用两个perl模块(JSON和XML :: Simple)来执行fly-by转换:
cat test.json | perl -MJSON -MXML::Simple -e 'print XMLout(decode_json(do{local$/;<>}),RootName=>"json")'
对于你的例子json最终为:
<json age="200" firstName="Bender" lastName="Robot">
<address city="New York" postalCode="1729" state="NY" streetAddress="123" />
<phoneNumber number="666 555-1234" type="home" />
<phoneNumber number="666 555-4567" type="fax" />
</json>
答案 3 :(得分:4)
答案 4 :(得分:3)
最近我发现JSON很容易被eval
- 用Python编写:
$ python -c "json=eval(open('/json.txt').read()); print len(json['phoneNumber'])"
2
虽然如果JSON输入包含空值,该方法显然会失败。
答案 5 :(得分:2)
查看f:json-document()
中的FXSL 2.x library。
使用此函数非常容易合并JSon并将其用作... XML。
例如,可以编写以下XPath表达式:
f:json-document($vstrParam)/Students/*[sex = 'Female']
和让Students
的所有孩子都拥有sex = 'Female'
以下是完整示例:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f xs"
>
<xsl:import href="../f/func-json-document.xsl"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vstrParam" as="xs:string">
{
"teacher":{
"name":
"Mr Borat",
"age":
"35",
"Nationality":
"Kazakhstan"
},
"Class":{
"Semester":
"Summer",
"Room":
null,
"Subject":
"Politics",
"Notes":
"We're happy, you happy?"
},
"Students":
{
"Smith":
{"First Name":"Mary","sex":"Female"},
"Brown":
{"First Name":"John","sex":"Male"},
"Jackson":
{"First Name":"Jackie","sex":"Female"}
}
,
"Grades":
{
"Test":
[
{"grade":"A","points":68,"grade":"B","points":25,"grade":"C","points":15},
{"grade":"C","points":2, "grade":"B","points":29, "grade":"A","points":55},
{"grade":"C","points":2, "grade":"A","points":72, "grade":"A","points":65}
]
}
}
</xsl:variable>
<xsl:template match="/">
<xsl:sequence select=
"f:json-document($vstrParam)/Students/*[sex = 'Female']"/>
</xsl:template>
</xsl:stylesheet>
当对任何XML文档应用上述转换(忽略)时,会生成正确的结果:
<Smith>
<First_Name>Mary</First_Name>
<sex>Female</sex>
</Smith>
<Jackson>
<First_Name>Jackie</First_Name>
<sex>Female</sex>
</Jackson>
答案 6 :(得分:1)
幸运的是,在XML领域,我们拥有诸如XPath,XQuery和XSLT之类的出色技术来帮助我们。
[...]
所以这引出了我的问题:是否有类似JSON的工具?
如果您问我,Xidel正是您想要的。
Xidel是一个命令行工具,可以使用CSS,XPath 3.0,XQuery 3.0,JSONiq或模式模板从HTML / XML页面或JSON-API下载和提取数据。它还可以创建新的或转换后的XML / HTML / JSON文档。
查询:
xidel -s "input.json" \
-e '
$json/avg(
count(
(phoneNumber)()
)
)
'
或
xidel -s "input.json" -e '$json/avg(count((phoneNumber)()))'
输出:
2
答案 7 :(得分:0)
还有交互式终端工具-fx
将任何JSON和匿名函数放入fx中以进行简化。
$ echo '{...}' | fx [code ...]
在不传递任何参数的情况下启动交互模式:
$ curl ... | fx