2016-09-19 88 views
1

我有一个JSON对象的流文件如下:猛砸有JQ分组

{"id":4496,"status":"Analyze","severity":"Critical","severityCode":1,"state":"New","code":"RNPD.DEREF","title":"Suspicious dereference of pointer before NULL check","message":"Suspicious dereference of pointer \u0027peer-\u003esctSapCb\u0027 before NULL check at line 516","file":"/home/build/branches/mmm/file1","method":"CzUiCztGpReq","owner":"unowned","taxonomyName":"C and C++","dateOriginated":1473991086512,"url":"http://xxx/yyy","issueIds":[4494]} 
{"id":4497,"status":"Analyze","severity":"Critical","severityCode":1,"state":"New","code":"NPD.GEN.CALL.MIGHT","title":"Null pointer may be passed to function that may dereference it","message":"Null pointer \u0027tmpEncodedPdu\u0027 that comes from line 346 may be passed to function and can be dereferenced there by passing argument 1 to function \u0027SCpyMsgMsgF\u0027 at line 537.","file":"/home/build/branches/mmm/file1","method":"CzUiCztGpReq","owner":"unowned","taxonomyName":"C and C++","dateOriginated":1473991086512,"url":"http://xxx/yyy/zzz","issueIds":[4495]} 
{"id":4498,"status":"Analyze","severity":"Critical","severityCode":1,"state":"New","code":"NPD.GEN.CALL.MIGHT","title":"Null pointer may be passed to function that may dereference it","message":"Null pointer \u0027tmpEncodedPdu\u0027 that comes from line 346 may be passed to function and can be dereferenced there by passing argument 1 to function \u0027SCpyMsgMsgF\u0027 at line 537.","file":"/home/build/branches/mmm/otherfile.c","method":"CzUiCztGpReq","owner":"unowned","taxonomyName":"C and C++","dateOriginated":1473991086512,"url":"http://xxx/yyy/zzz","issueIds":[4495]} 

我想与JQ获得(或其他方式),三行,每一个的ID ,网址和文件名:

这是我到目前为止有:

cat /tmp/file.json | ~/bin_compciv/jq --raw-output '.id,.url,.file' 

结果:

4496 
http://xxx/yyy 
/home/build/branches/mmm/file1 
. 
. 
. 

- 我想将它们分组按文件名,这样我会得到URL和ID的逗号分隔列表放在同一行,像这样:

4496,4497 
http://xxx/yyy,http://xxx/yyy/zzz 
/home/build/branches/mmm/file1 
+0

更好运行'jq ...

+0

这对于'jq'来说并不重要,但是对sort分类很重要 - 如果它有一个真正的文件句柄,那么'sort'的优化实现可以使子进程寻求不同的部分文件,并行排序组件,然后在父进程中进行合并排序;使用不可寻址的FIFO进行输入时,如果没有不可并行的初始读取通道,则无法进行这种优化,因为输入流只能从前到后只读取一次。 –

回答

0

有了一个小小的例外,你可以很容易地实现使用JQ既定目标如下:

jq -scr 'map({id,url,file}) 
    | group_by(.file) 
    | .[] 
    | ((map(.id) | @csv) , (map(.url) | @csv), (.[0] | .file))' 

鉴于你的输入,输出会是:

4496,4497 
"http://xxx/yyy","http://xxx/yyy/zzz" 
/home/build/branches/mmm/file1 
4498 
"http://xxx/yyy/zzz" 
/home/build/branches/mmm/otherfile.c 

然后,您可以使用文本编辑工具(如sed)消除引号;使用另一个调用jq;或如下所述。但是,如果任何URL都有逗号的话,这可能不是一个好主意。

下面是消除只有一个调用JQ的引号过滤器:

map({id,url,file}) 
| group_by(.file) 
| .[] 
| ((map(.id) | @csv), 
    ([map(.url) | join(",")] | @csv | .[1:-1]), 
    (.[0] | .file)) 
+0

看起来像是我在找什么。但是像这样运行它: cat /tmp/file.json | 〜/ bin_compciv/jq -scr'map({id,url,file})| GROUP_BY(.file)| 。[] | ((地图(.id)| @csv),(地图(.url)| @csv))' 它说-scr不被识别。尝试没有-scr,出现错误:“jq:错误:无法用字符串索引数组 jq:错误:数组在csv行无效” – OkyDokyman

+0

显然,您没有使用最新版本的jq(1.5)。如果您使用1.4版,请使用“-s -c -r”而不是-scr。如果您使用1.3,则可能需要其他更改,但最好升级到v1.4。 – peak

0

下面是使用GROUP_BY-r-s JQ选择一个解决方案:

group_by(.file)[] 

| ([ "\(.[].id)" ] | join(",")), 
    ([ .[].url  ] | join(",")), 
    .[0].file