2016-09-19 5 views
1

У меня есть файл с потоком объектов JSON следующим образом:Bash с 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 (или каким-либо другим способом), три линии, один для каждого из идентификаторов , URL-адреса, и имя файла:

Это то, что я до сих пор:

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

Результат:

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

НО - Я хотел бы сгруппировать их по имени файла, так что я буду получать через запятую списки адресов и идентификаторов на той же линии, как это:

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) | . [] | ((map (.id) | @csv), (map (.url) | @csv)) ' В нем указано -scr не распознается. Пробовал без -scr, получил ошибку: «jq: error: не удается индексировать массив со строкой jq: ошибка: массив недопустим в строке csv» – OkyDokyman

+0

Очевидно, вы не используете последнюю версию jq (1.5). Если вы используете v. 1.4, используйте «-s -c -r» вместо -scr. Если вы используете 1.3, могут потребоваться другие изменения, но было бы предпочтительнее обновить, по крайней мере, до версии 1.4. – peak

0

Вот решение, которое использует group_by и -r, -s варианты JQ:

group_by(.file)[] 

| ([ "\(.[].id)" ] | join(",")), 
    ([ .[].url  ] | join(",")), 
    .[0].file 
Смежные вопросы