Bash, получить значения из файла JSON, все в одной строке

Возможно ли получить данные для одного конкретного продукта, закрытого в { }, из json, по EAN, все данные находятся в одной строке?

Пример

Ввод.

...

{ "article": {"code": "01333457004","name": "ALAZANIS VALLEY 2015","note": "ČERV VÍNO EVROPA VÝCH OSTATNÍ","sel_unit": "Kus","unit_price": 229.0,"category": "ČERVENÉ,POLOSLADKÉ","unit": "L","EAN": "4867601700052","unit_volume": 0.75,"producer": null,"tax": 21.0,"text": "Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;","is_action": "1","action_from": "20190905","action_to": "20190918","ordered_from": "20190126","ordered_to": "20190830","shelf_id": "1030542","is_outlet": 0}},{ "article" ...

...

Ожидаемый результат (команда выбрана code 01333457004) через sed или awk?

{ "article": {"code": "01333457004","name": "ALAZANIS VALLEY 2015","note": "ČERV VÍNO EVROPA VÝCH OSTATNÍ","sel_unit": "Kus","unit_price": 229.0,"category": "ČERVENÉ,POLOSLADKÉ","unit": "L","EAN": "4867601700052","unit_volume": 0.75,"producer": null,"tax": 21.0,"text": "Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;","is_action": "1","action_from": "20190905","action_to": "20190918","ordered_from": "20190126","ordered_to": "20190830","shelf_id": "1030542","is_outlet": 0}}

Спасибо.

2
задан 9 September 2019 в 12:12

2 ответа

Я просто разделил бы файл на одну запись на строку сначала. Это делает парсинг его намного более простым. Так, найдите все случаи },{ и добавьте новую строку, повреждающую их:

$ sed 's/},{/},\n{/g' file
{ "article": {"code": "01333457004","name": "ALAZANIS VALLEY 2015","note": "ČERV VÍNO EVROPA VÝCH OSTATNÍ","sel_unit": "Kus","unit_price": 229.0,"category": "ČERVENÉ,POLOSLADKÉ","unit": "L","EAN": "4867601700052","unit_volume": 0.75,"producer": null,"tax": 21.0,"text": "Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;","is_action": "1","action_from": "20190905","action_to": "20190918","ordered_from": "20190126","ordered_to": "20190830","shelf_id": "1030542","is_outlet": 0}},
{ "article" ...

Теперь, можно просто искать код. Но используйте -w флаг для grep который заставляет его искать "слова", чтобы не находить код как подстроку. Таким образом, если у Вас есть одна строка с кодом 01333457004 и другая строка с кодом 013334570041, поиск 01333457004 не найдет 013334570041.

Соединение всего этого дает:

$ sed 's/},{/},\n{/g' file | grep 01333457004
{ "article": {"code": "01333457004","name": "ALAZANIS VALLEY 2015","note": "ČERV VÍNO EVROPA VÝCH OSTATNÍ","sel_unit": "Kus","unit_price": 229.0,"category": "ČERVENÉ,POLOSLADKÉ","unit": "L","EAN": "4867601700052","unit_volume": 0.75,"producer": null,"tax": 21.0,"text": "Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;","is_action": "1","action_from": "20190905","action_to": "20190918","ordered_from": "20190126","ordered_to": "20190830","shelf_id": "1030542","is_outlet": 0}},

Если Вы действительно хотите сделать это в единственной операции, можно попытаться использовать grep с -P для регулярных выражений PCRE, которые поддерживают предвидения:

$ grep -oP '{ "article":.*?\b01333457004\b.*?}(?=,{)' file
{ "article": {"code": "01333457004","name": "ALAZANIS VALLEY 2015","note": "ČERV VÍNO EVROPA VÝCH OSTATNÍ","sel_unit": "Kus","unit_price": 229.0,"category": "ČERVENÉ,POLOSLADKÉ","unit": "L","EAN": "4867601700052","unit_volume": 0.75,"producer": null,"tax": 21.0,"text": "Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;Alazanis Valley 2015;Gruzie,Kachetie;červené polsladké;750ml;16°C;","is_action": "1","action_from": "20190905","action_to": "20190918","ordered_from": "20190126","ordered_to": "20190830","shelf_id": "1030542","is_outlet": 0}}

Это будет искать { "article":, затем самый короткий фрагмент 0 или больше символов (.*?) до строки 01333457004, но только если это кажется окруженным несловесными символами, поэтому только если это - слово; это что \b средний, затем самый короткий фрагмент 0 или больше символов снова тот конец с a } сопровождаемый ,}.

1
ответ дан 2 December 2019 в 03:26

Можно использовать jq.

Взгляните на это

Вероятно, в Вашем случае это должно быть что-то как:

cat test.json | jq '.[] | select(.article.code | contains("01333457004"))'
1
ответ дан 2 December 2019 в 03:26

Другие вопросы по тегам:

Похожие вопросы: