一般问题
尽管我可能在诊断事件的根本原因,确定它影响了多少用户,或者提取计时日志以评估最近代码更改的性能和吞吐量影响,但我的工具保持不变:grep
、awk
、sed
、tr
、uniq
、sort
、zcat
、tail
、head
、<代码>D9和<代码>D10。为了将它们粘合在一起,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>
假设我想生成一个从用户到每个<foo>
的平均<baz>
数的映射。逐行处理不再是一种选择:我需要知道我当前正在检查哪个用户的<foo>
,这样我才能知道要更新谁的平均值。任何一种完成这项任务的Unix one liner都很可能是难以捉摸的。
幸运的是,在XML领域,我们有像XPath、XQuery和XSLT这样的优秀技术来帮助我们。
以前,我已经习惯于使用出色的XML模块来完成像上面这样的查询,但是在找到TextMate Plugin that could run an XPath expression against my current window之后,我不再编写一次性的XML::XPath
脚本来查询TextMate Plugin that could run an XPath expression against my current window。我刚刚发现了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" }
]
}
想要找出每个人的平均电话号码,我可以用XPath做这样的事情:
fn:avg(/fn:count(phoneNumber))
问题
我注意到越来越多的数据序列化是使用JSON完成的,所以这样的处理工具在将来分析大型数据转储时将是至关重要的。JSON的语言库非常强大,编写脚本来完成这类处理非常容易,但要真正让人们尝试一下数据shell工具是必需的。
相关问题
发布于 2013-01-03 12:00:27
我发现了这个:
http://stedolan.github.com/jq/
"jq是一个轻量级、灵活的命令行JSON处理器。“
2014年更新:
@user456584提到:
还有'json‘命令(例如'jsontool')。我倾向于喜欢它而不是jq。非常的UNIX-y。
在http://github.com/trentm/json的json
自述文件中有一长串类似的东西
http://code.google.com/p/jsonpath/wiki/Javascript
,
发布于 2012-04-17 07:01:56
我已经创建了一个专门为命令行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中添加问题。我已经设计了一个相当广泛的功能集,但我很乐意优先考虑社区成员需要的功能。
发布于 2010-05-29 08:03:38
一种方法是将其转换为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>
https://stackoverflow.com/questions/2933126
复制相似问题