JSON有什么好的CLI工具?
一般问题
虽然我可能正在诊断事件的根本原因,确定它影响的用户数量,或提取定时日志以评估最近代码更改的性能和吞吐量影响,但我的工具保持不变: grep
, awk
, sed
, tr
, uniq
, sort
, zcat
, tail
, head
, join
和split
。 为了把它们粘在一起,Unix给了我们pipe道,为了更好的过滤,我们有了xargs
。 如果这些让我失望,总会有perl -e
。
这些工具非常适合处理CSV文件,制表符分隔的文件,具有可预测的行格式的日志文件或使用逗号分隔的键值对的文件。 换句话说,每行有没有上下文的文件。
XML类似物
我最近需要浏览Gigabytes的XML来构build一个用户使用的直方图。 对于我所用的工具来说,这很简单,但对于更复杂的查询,正常的方法会失败。 说我有像这样的项目的文件:
<foo user="me"> <baz key="zoidberg" value="squid" /> <baz key="leela" value="cyclops" /> <baz key="fry" value="rube" /> </foo>
假设我想产生一个从用户到平均数<baz>
s per <foo>
的映射。 逐行处理不再是一个select:我需要知道哪个用户的<foo>
我正在检查,所以我知道谁的平均更新。 完成这个任务的任何一种Unix单线程都可能是不可思议的。
幸运的是,在XML-land中,我们拥有诸如XPath,XQuery和XSLT等奇妙技术来帮助我们。
以前,我已经习惯于使用美妙的XML::XPath
Perl模块来完成像上面那样的查询,但是在find一个可以在当前窗口运行XPathexpression式的TextMate插件之后,我停止编写一次性的Perl脚本查询XML。 而且我刚刚发现了正在安装的XMLStarlet ,我正在打字,而且我期待在将来使用它。
JSON解决scheme?
所以这导致我的问题:有没有像这样的JSON的工具? 一些调查任务要求我对JSON文件进行类似查询只是一个时间问题,而没有像XPath和XSLT这样的工具,这样的任务将会困难得多。 如果我有一堆看起来像这样的JSON:
{ "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" } ] }
并想find每个人的电话号码的平均数量,我可以用XPath做这样的事情:
fn:avg(/fn:count(phoneNumber))
问题
- 有没有可以用这种方式“查询”JSON文件的命令行工具?
- 如果你必须在Unix命令行上处理一堆JSON文件,你使用了什么工具?
- 嘿,是否有工作正在做这样的JSON查询语言?
- 如果你在日常工作中使用这样的工具,你喜欢/不喜欢他们呢? 有什么问题吗?
我注意到越来越多的数据序列化正在使用JSON来完成,所以在将来分析大数据转储时,这样的处理工具将是至关重要的。 用于JSON的语言库非常强大,编写脚本来完成这种处理非常简单,但要真正让人们使用数据shell工具,还是需要的。
相关问题
- 用于XML命令行处理的Grep和Sed等效
- 有没有JSON的查询语言?
- JSONPath或其他XPath类似于JSON / Javascript的实用工具; 或者Jquery JSON
我刚刚发现这个:
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:select : 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
我创build了一个专门用于命令行JSON操作的模块:
https://github.com/ddopson/underscore-cli
- 灵活 – 用于处理JSON数据的“瑞士军刀”工具可以用作简单的漂亮打印机,也可以用作全function的JavaScript命令行
- 强大 – 揭示了underscore.js的全部function和function(加上underscore.string)
- 简单 – 使用类似于使用“perl -pe”编写JS单行程序很简单
- CHAINED – 可以将多个命令调用链接在一起以创build数据处理pipe道
- 多格式 – 丰富的input/输出格式支持 – 漂亮的打印,严格的JSON等[即将推出]
- 文档 – 每个命令都有多个示例的优秀命令行文档
它可以让你真正轻松地做强大的事情:
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
它有一个非常好的命令行帮助系统, 非常灵活。 它已经过很好的testing并可以使用。 不过,我仍然构build了一些input/输出格式替代scheme,并合并到我的模板处理工具中(参见TODO.md)。 如果你有任何function请求,评论这个职位或在github中添加一个问题。 我devise了一个相当广泛的function集,但是我很乐意优先考虑社区成员需要的function。
你可以做的一个方法是将其转换为XML。 以下使用两个perl模块(JSON和XML :: Simple)进行飞行转换:
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>
看看这个疯狂的项目jsawk 。 这是devise,通过从命令行JSONinput过滤。 对于可以在可能派上用场的pipe道中使用的命令行REST客户端,请检查resty 。
最近我发现可以很容易地用Python eval
JSON:
$ python -c "json=eval(open('/json.txt').read()); print len(json['phoneNumber'])" 2
虽然如果JSONinput包含空值,该方法显然会失败。
看看FXSL 2.x库中的f:json-document()
。
使用这个函数,很容易将JSon合并并像XML一样使用它。
例如,可以编写以下XPathexpression式:
f:json-document($vstrParam)/Students/*[sex = 'Female']
并获得sex = 'Female'
的Students
所有孩子
这是一个完整的例子:
<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>