Как пропустить json-файл?

У меня есть json-файл ниже, и я хочу получить hostId, только если name содержит определенное значение. Я хочу использовать сценарий оболочки для этого.

 { "items" : [ { "name" : "first-block-e70a2fe8fd0531ad1f87de49f03537a6", "type" : "STORE", "hostRef" : { "hostId" : "166219e3-be5c-46d0-b4c7-33543a29ce32" }, "roleState" : "STARTED", "healthSummary" : "GOOD", }, { "name" : "second-block-c21a1ae8dd2831cd1b87de49f98274e8", "type" : "STORE", "hostRef" : { "hostId" : "176429e3-be5c-46d0-b4c7-33543a29ad63" }, "roleState" : "STARTED", "healthSummary" : "GOOD", } { "name" : "first-block-a85d2fe6fd0482ad1f54de49f45174a0", "type" : "STORE", "hostRef" : { "hostId" : "176429e3-ae1d-46d0-b4c7-66123a24fa82" }, "roleState" : "STARTED", "healthSummary" : "GOOD", } } 

Например: если имя содержит что-то с «первым блоком», тогда я должен получить hosdId как

 166219e3-be5c-46d0-b4c7-33543a29ce32 176429e3-ae1d-46d0-b4c7-66123a24fa82 

Как я могу перебирать json-файл? Какое регулярное выражение следует использовать для фильтрации элемента, который содержит определенное значение по name и получает hostid ?

4 Solutions collect form web for “Как пропустить json-файл?”

Очень простой пример с использованием python:

 #!/usr/bin/env python import sys import json def print_first(data): for item in data["items"]: if item["name"].startswith("first"): print item["hostRef"]["hostId"] def main(argv): for json_file in argv: with open(json_file) as data_file: data = json.load(data_file) print_first(data) if __name__ == "__main__": main(sys.argv[1:]) 

То есть с вашими образцами данных, отформатированными как:

 { "items" : [ { "name" : "first-block-e70a2fe8fd0531ad1f87de49f03537a6", "type" : "STORE", "hostRef" : { "hostId" : "166219e3-be5c-46d0-b4c7-33543a29ce32" }, "roleState" : "STARTED", "healthSummary" : "GOOD" }, { "name" : "second-block-c21a1ae8dd2831cd1b87de49f98274e8", "type" : "STORE", "hostRef" : { "hostId" : "176429e3-be5c-46d0-b4c7-33543a29ad63" }, "roleState" : "STARTED", "healthSummary" : "GOOD" }, { "name" : "first-block-a85d2fe6fd0482ad1f54de49f45174a0", "type" : "STORE", "hostRef" : { "hostId" : "176429e3-ae1d-46d0-b4c7-66123a24fa82" }, "roleState" : "STARTED", "healthSummary" : "GOOD" } ] } 

Вы можете использовать jq:

Входной файл:

 { "items" : [ { "name" : "first-block-e70a2fe8fd0531ad1f87de49f03537a6", "type" : "STORE", "hostRef" : { "hostId" : "166219e3-be5c-46d0-b4c7-33543a29ce32" }, "roleState" : "STARTED", "healthSummary" : "GOOD" }, { "name" : "second-block-c21a1ae8dd2831cd1b87de49f98274e8", "type" : "STORE", "hostRef" : { "hostId" : "176429e3-be5c-46d0-b4c7-33543a29ad63" }, "roleState" : "STARTED", "healthSummary" : "GOOD" }, { "name" : "first-block-a85d2fe6fd0482ad1f54de49f45174a0", "type" : "STORE", "hostRef" : { "hostId" : "176429e3-ae1d-46d0-b4c7-66123a24fa82" }, "roleState" : "STARTED", "healthSummary" : "GOOD" } ] } 

команда:

Изменить: с помощью вклада @ Runium

 $ jq '.items[] | select( .name | startswith("first-block-"))|.hostRef.hostId' < file.json "e70a2fe8fd0531ad1f87de49f03537a6" "a85d2fe6fd0482ad1f54de49f45174a0" 

Как отметил @Theophrastus, вы хотите сначала установить парсер JSON jq . После этого, это просто вопрос фильтрации для требуемого значения.

Я должен упомянуть, что блок JSON, который вы опубликовали, недействителен; открывающая скобка «предметов» не закрыта, а вторая запись в items должна иметь разделитель запятой. Несмотря на это, я собираюсь предположить, что у вас есть действующий блок, и только вырезать и вставить то, что вы считаете релевантным. Если каждый блок действительно репрезентативен, то все, что вам нужно добавить, это (предполагая, что bash – это ваша оболочка)

 echo "${YOUR_JSON_BLOCK}" | jq '.items[].hostRef.hostId' 

Это будет выводить только эти строки, как указано, если YOUR_JSON_BLOCK – это полная действительная строка json с вашими данными.

jq уже упоминалось несколько раз, поэтому я упомянул jsonpipe . Он преобразует данные json в линейно ориентированный формат, подходящий для обработки с помощью командных инструментов, таких как grep , sed , awk , perl и т. Д. Это инструмент командной строки для работы с json в оболочке и библиотека python.

Например, если ваши данные примера json сохраняются в файле с именем alex.json , а затем отредактированы так, чтобы он действительно действовал json:

 $ jsonpipe < alex.json / {} /items [] /items/0 {} /items/0/name "first-block-e70a2fe8fd0531ad1f87de49f03537a6" /items/0/type "STORE" /items/0/hostRef {} /items/0/hostRef/hostId "166219e3-be5c-46d0-b4c7-33543a29ce32" /items/0/roleState "STARTED" /items/0/healthSummary "GOOD" /items/1 {} /items/1/name "second-block-c21a1ae8dd2831cd1b87de49f98274e8" /items/1/type "STORE" /items/1/hostRef {} /items/1/hostRef/hostId "176429e3-be5c-46d0-b4c7-33543a29ad63" /items/1/roleState "STARTED" /items/1/healthSummary "GOOD" /items/2 {} /items/2/name "first-block-a85d2fe6fd0482ad1f54de49f45174a0" /items/2/type "STORE" /items/2/hostRef {} /items/2/hostRef/hostId "176429e3-ae1d-46d0-b4c7-66123a24fa82" /items/2/roleState "STARTED" /items/2/healthSummary "GOOD" 

Затем вы можете передать его в awk, чтобы извлечь все, что выглядит как hostId во втором поле диапазона, начиная с шаблона / first-block / и заканчивая / hostId /.

 $ jsonpipe < alex.json | awk '/first-block/,/hostId/ { if ($2 ~ /\"[a-f0-9]{8}-/) { gsub(/\"/,"",$2); print $2 } }' 166219e3-be5c-46d0-b4c7-33543a29ce32 176429e3-ae1d-46d0-b4c7-66123a24fa82 

BTW, вы можете получить выход jsonpipe в формате «абзац», причем каждый «элемент» в отдельном абзаце, передавая его в sed . например, в этом случае добавить новую строку перед каждой записью.

 $ jsonpipe < alex.json | sed -e 's/\/items\/[[:digit:]]\+[[:blank:]]\+/\n&/' / {} /items [] /items/0 {} /items/0/name "first-block-e70a2fe8fd0531ad1f87de49f03537a6" /items/0/type "STORE" /items/0/hostRef {} /items/0/hostRef/hostId "166219e3-be5c-46d0-b4c7-33543a29ce32" /items/0/roleState "STARTED" /items/0/healthSummary "GOOD" /items/1 {} /items/1/name "second-block-c21a1ae8dd2831cd1b87de49f98274e8" /items/1/type "STORE" /items/1/hostRef {} /items/1/hostRef/hostId "176429e3-be5c-46d0-b4c7-33543a29ad63" /items/1/roleState "STARTED" /items/1/healthSummary "GOOD" /items/2 {} /items/2/name "first-block-a85d2fe6fd0482ad1f54de49f45174a0" /items/2/type "STORE" /items/2/hostRef {} /items/2/hostRef/hostId "176429e3-ae1d-46d0-b4c7-66123a24fa82" /items/2/roleState "STARTED" /items/2/healthSummary "GOOD" 

Данные, разделенные абзацами, являются очень распространенным форматом, а общие инструменты, такие как awk и sed и perl 1, имеют функции, облегчающие работу с параграфами. Кроме того, есть много примеров такой работы, которые легко найти на этом и других сайтах SE, а также в google.

Наконец, jsonpipe имеет аналог jsonunpipe чтобы преобразовать этот линейно-ориентированный плоский формат обратно в json.

Например, если вы хотите сгладить структуру так, чтобы hostId был свойством самого элемента, а не hostRef:

 $ jsonpipe < alex.json | sed -e '/hostRef[[:blank:]]/d;s/hostRef\///' | jsonunpipe {"items": [{"name": "first-block-e70a2fe8fd0531ad1f87de49f03537a6", "type": "STORE", "hostId": "166219e3-be5c-46d0-b4c7-33543a29ce32", "roleState": "STARTED", "healthSummary": "GOOD"}, {"name": "second-block-c21a1ae8dd2831cd1b87de49f98274e8", "type": "STORE", "hostId": "176429e3-be5c-46d0-b4c7-33543a29ad63", "roleState": "STARTED", "healthSummary": "GOOD"}, {"name": "first-block-a85d2fe6fd0482ad1f54de49f45174a0", "type": "STORE", "hostId": "176429e3-ae1d-46d0-b4c7-66123a24fa82", "roleState": "STARTED", "healthSummary": "GOOD"}]} 

Если необходимо, вы можете jq это через jq или json_pp или аналогично тому, чтобы печатать его для удобства чтения.


1 perl имеет несколько превосходных модулей для синтаксического анализа и обработки json-данных, поэтому вам, вероятно, лучше использовать один из них. Всякий раз, когда вы обнаруживаете, что вы трахаете данные из grep , sed и / или awk в perl , вы действительно должны спросить себя: «Почему я это делаю? Это безумие, я просто должен все это сделать в perl». То же самое можно сказать и о python .

  • bash: назначить переменную и вывести на стандартный вывод в той же команде
  • Найти файл JSON проверить, если сгенерировано или выполнить
  • Где я могу найти сценарий оболочки для разбора JSON на busybox?
  • отправить json через rsyslog в elasticsearch
  • Замена содержимого файла SED в 2 файлах
  • Извлеките значение из вывода команды и используйте значение в качестве параметра для следующей команды
  • захватить текст из файла vtt
  • Загрузите документы, на которые ссылается веб-страница с wget
  • Удаление нескольких строк
  • Как форматировать потоковый вывод JSON из Node.js?
  • JSON с переменным ключом в bash
  • Linux и Unix - лучшая ОС в мире.