У меня есть файл 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",
}
}
Например: если имя содержит что-то с 'first-block', то я должен получить hosdId как
166219e3-be5c-46d0-b4c7-33543a29ce32
176429e3-ae1d-46d0-b4c7-66123a24fa82
Как мне выполнить итерацию по файлу json? Какое регулярное выражение мне следует использовать для фильтрации элемента, содержащего определенное значение, name
и получения hostid
?
решение1
Вы можете использовать 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"
решение2
Очень простой пример с использованием 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"
}
]
}
решение3
Как упомянул @Theophrastus, сначала нужно установить парсер JSON jq
. После этого останется только отфильтровать нужное значение.
Я должен упомянуть, что блок JSON, который вы разместили, недействителен; открывающая скобка "items" не закрыта, а вторая запись items
должна иметь запятую-разделитель. Несмотря на это, я предполагаю, что у вас есть действительный блок, и вы скопировали и вставили только то, что посчитали релевантным. Если каждый блок действительно репрезентативен, то все, что вам нужно добавить, это (предполагая, bash
что это ваша оболочка)
echo "${YOUR_JSON_BLOCK}" | jq '.items[].hostRef.hostId'
Это выведет только те строки, которые указаны, предполагая, что YOUR_JSON_BLOCK — это полная допустимая строка JSON с вашими данными.
решение4
Недавно я придумал более простую альтернативу Unix/Shell (она полностью FOSS и бесплатна) для обработки таких запросов JSON — взгляните наjtc
Инструмент позволяет обрабатывать относительные обходы (т. е. находить один и затем смещаться к другому).
Если предположить, что ваш исходный json исправлен (в нем есть несколько проблем), то cli будет выглядеть так:
bash $ cat file.json | jtc -w'[name]:<^first-block>R: [-1] [hostRef] [hostId]'
"166219e3-be5c-46d0-b4c7-33543a29ce32"
"176429e3-ae1d-46d0-b4c7-66123a24fa82"
bash $