什么是JSON的良好CLI工具?

jas*_*p85 59 xslt xpath command-line json

一般问题

虽然我可以诊断事件的根本原因,确定有多少用户受到影响,或蒸馏时间日志,以评估性能和近期代码更改吞吐量的影响,我的工具保持不变:grep,awk,sed,tr,uniq,sort,zcat,tail,head,join,和split.为了将它们粘合在一起,Unix为我们提供了管道,并且我们有更好的过滤xargs.如果这些让我失望,那就永远都是perl -e.

这些工具非常适合处理CSV文件,制表符分隔文件,具有可预测行格式的日志文件或具有逗号分隔键值对的文件.换句话说,每行都没有上下文的文件.

XML类似物

我最近需要浏览千兆字节的XML来构建用户的直方图.使用我的工具这很容易,但对于更复杂的查询,正常的方法会崩溃.假设我的文件包含以下内容:

<foo user="me">
    <baz key="zoidberg" value="squid" />
    <baz key="leela"    value="cyclops" />
    <baz key="fry"      value="rube" />
</foo>
Run Code Online (Sandbox Code Playgroud)

让我们说我想生成一个从用户到平均<baz>每个s 的映射<foo>.逐行处理不再是一个选项:我需要知道<foo>我正在检查哪个用户,所以我知道要更新的平均值.完成这项任务的任何类型的Unix一行都可能是不可理解的.

幸运的是,在XML-land中,我们有很多精彩的技术,如XPath,XQuery和XSLT来帮助我们.

以前,我已经习惯使用精彩的XML::XPathPerl模块来完成上面的查询,但在找到可以针对当前窗口运行XPath表达式TextMate插件后,我停止编写一次性Perl脚本来查询XML.我刚刚发现了正在安装的XMLStarlet,因为我输入了这个,并且我期待将来使用它.

JSON解决方案?

所以这引出了我的问题: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" }
  ]
}
Run Code Online (Sandbox Code Playgroud)

并且想要找到每个人的平均电话号码数量,我可以用XPath做这样的事情:

fn:avg(/fn:count(phoneNumber))
Run Code Online (Sandbox Code Playgroud)

问题

  1. 有没有可以用这种方式"查询"JSON文件的命令行工具?
  2. 如果你必须在Unix命令行上处理一堆JSON文件,你使用什么工具?
  3. 哎呀,有没有工作要为JSON制作这样的查询语言?
  4. 如果你在日常工作中使用这样的工具,你对它们喜欢/不喜欢什么?有没有陷阱?

我注意到越来越多的数据序列化正在使用JSON完成,因此在将来分析大型数据转储时,这样的处理工具将至关重要.JSON的语言库非常强大,编写脚本很容易进行这种处理,但真正让人们玩数据shell工具是必需的.

相关问题

Bri*_*gle 53

我刚发现这个:

http://stedolan.github.com/jq/

"jq是一个轻量级且灵活的命令行JSON处理器."

2014年更新:

@ user456584提到:

还有'json'命令(例如'jsontool').我倾向于喜欢它而不是jq.很UNIX-y.这是该项目的链接:github.com/trentm/json -

http://github.com/trentm/jsonjsonREADME中,有很多类似的东西

  • @ZachGarner,JQ支持字符串插值 - 因此您可以生成非JSON的输出.有关示例,请参见[我在UNIX SE上的答案](http://unix.stackexchange.com/a/254243/1131). (2认同)

Dav*_*son 7

我创建了一个专门用于命令行JSON操作的模块:

https://github.com/ddopson/underscore-cli

  • 灵活 - 用于处理JSON数据的"瑞士军刀"工具 - 可以用作简单的漂亮打印机,也可以用作全功能的Javascript命令行
  • 强大 - 暴露了underscore.js的全部功能和功能(加上underscore.string)
  • 简单 - 使用类似于使用"perl -pe"的JS单行编写简单
  • CHAINED - 可以将多个命令调用链接在一起以创建数据处理管道
  • 多格式 - 丰富的输入/输出格式支持 - 漂亮的打印,严格的JSON等[即将推出]
  • DOCUMENTED - 出色的命令行文档,每个命令都有多个示例

它可以让你轻松地做强大的事情:

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
Run Code Online (Sandbox Code Playgroud)

它有一个非常好的命令行帮助系统,非常灵活.经过充分测试,可随时使用; 但是,我仍然在构建一些功能,比如输入/输出格式的替代品,以及我的模板处理工具中的合并(参见TODO.md).如果您有任何功能请求,请对此帖子发表评论或在github中添加问题.我设计了一个非常广泛的功能集,但我很乐意优先考虑社区成员所需的功能.


aza*_*oth 5

您可以做的一种方法是将其转换为XML.下面使用两个perl模块(JSON和XML :: Simple)来执行fly-by转换:

cat test.json | perl -MJSON -MXML::Simple -e 'print XMLout(decode_json(do{local$/;<>}),RootName=>"json")'
Run Code Online (Sandbox Code Playgroud)

对于你的例子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>
Run Code Online (Sandbox Code Playgroud)

  • 但是,这仍然不像是一流的JSON工具.您基本上只是使用一种对JSON和XML有良好支持的编程语言,然后重新使用XML工具进行实际处理. (2认同)

Ant*_*dev 5

还有交互式终端工具\xe2\x80\x94 fx

\n\n

通过管道传入任何 JSON 和匿名函数以减少它。

\n\n
$ echo \'{...}\' | fx [code ...]\n
Run Code Online (Sandbox Code Playgroud)\n\n

启动交互模式而不传递任何参数:

\n\n
$ curl ... | fx\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n\n