Баш JQ;построить массив с использованием первичного ключа - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть цикл bash while do done в цикле, который выводит с использованием этого
echo "${KEY}: {\"${ATTRIBUTE}\": ${VALUE} }"

Входная часть 1

"PKEY1": {"rank": 1 }
"PKEY2": {"rank": 2 }
"PKEY3": {"rank": 4 }
"PKEY4": {"rank": 3 }

Входная часть 2

"PKEY1": {"attr": "xyz" }
"PKEY2": {"attr": "foo" }
"PKEY3": {"attr": "bar" }
"PKEY4": {"attr": "abc" }

Входная часть 3,4,5 и т. Д. *

Как я могу получить выходной файл или эхо, чтобы это выглядело вкратце

{
"PKEY1": {"rank": 1, "attr": "xyz" },
"PKEY2": {"rank": 2, "attr": "foo" },
"PKEY3": {"rank": 4, "attr": "bar" },
"PKEY4": {"rank": 3, "attr": "abc" }
}

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Указанную проблему можно разбить на две части:

1) синтаксический анализ текста пар key : value в допустимый JSON;

2) построение вывода

Так как формат текста ключ: значение четко не указан, я предполагаю, что каждая пара ключ: значение находится на отдельной строке, и что пара ключ / значение может быть восстановлена ​​с использованием def:

def parse: 
  capture("\"(?<k>[^\"]*)\" *: *(?<v>.*)") | [.k, (.v | fromjson)];

Вторая часть проблемы легко решается с помощью следующего общего определения:

def add_by(s; f; g):
  reduce s as $x (null; .[$x|f] += ($x|g));

Соединяя части, мы можем написать:

add_by(inputs | parse; .[0]; .[1])

Вызов

Используя приведенные выше фрагменты в файле merge.jq, мы можем написать:

jq -nR -f merge.jq part1.txt part2.txt part3.txt ...

Variant

Если ваша библиотека jq уже содержит:

def aggregate_by(s; f; g):
  reduce s as $x  (null; .[$x|f] += [$x|g]);

тогда вы можете использовать приведенное выше значение parse следующим образом:

aggregate_by(inputs | parse; .[0]; .[1])
| map_values(add)
0 голосов
/ 06 февраля 2019

То, что вы хотите, это объединить JSON.Если вы используете 1.4+, вы можете использовать: jq -s '.[0] * .[1]' file1 file2

Вы можете найти больше ответов здесь: Как объединить 2 файла json, используя jq?

...