JSON有什么好的CLI工具?

一般问题

虽然我可能正在诊断事件的根本原因,确定它影响的用户数量,或提取定时日志以评估最近代码更改的性能和吞吐量影响,但我的工具保持不变: grepawksedtruniqsortzcattailheadjoinsplit 。 为了把它们粘在一起,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)) 

问题

  1. 有没有可以用这种方式“查询”JSON文件的命令行工具?
  2. 如果你必须在Unix命令行上处理一堆JSON文件,你使用了什么工具?
  3. 嘿,是否有工作正在做这样的JSON查询语言?
  4. 如果你在日常工作中使用这样的工具,你喜欢/不喜欢他们呢? 有什么问题吗?

我注意到越来越多的数据序列化正在使用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>