Резюме:
Я успешно разработал способ удаления объектов в jq; однако рабочий код, который я написал, требует много повторений. Я чувствую, что, вероятно, есть более чистый или менее многословный способ достижения того же самого результата, и я хотел бы знать, что это такое.
Пример:
Используя следующую вложенную структуру компаний, предположим, что цель состоит в том, чтобы извлечь имя, ID, компанию и сайт для каждого человека в списке. (Мы можем игнорировать адрес.)
Введите:
{
"company": "Initrode",
"sites": [
{
"name": "HQ",
"address": "123 Main Street",
"personnel": [
{
"name": "John Smith",
"UID": 12345
},
{
"name": "Jane Doe",
"UID": 23456
}
]
},
{
"name": "Branch Office",
"address": "Spodunk, Nowhereville",
"personnel": [
{
"name": "Fred Anderson",
"UID": 56789
},
{
"name": "Bill Jones",
"UID": 34567
}
]
}
]
}
{
"company": "Inittech",
"sites": [
{
"name": "Main Office",
"address": "5678 Avenue Blvd",
"personnel": [
{
"name": "Fred Johnson",
"UID": 6543
},
{
"name": "James Fredson",
"UID": 9876
}
]
},
{
"name": "Testing Station",
"address": "Alaskan Wilderness",
"personnel": [
{
"name": "Sally May",
"UID": 5432
},
{
"name": "Jack James",
"UID": 8765
}
]
}
]
}
Рабочий код:
jq '{company,site: .sites[]}|
{company,site: .site.name,personnel: .site.personnel[]}|
{name: .personnel.name,id: .personnel.UID,company,site}' sample.json
Правильный вывод:
{
"name": "John Smith",
"id": 12345,
"company": "Initrode",
"site": "HQ"
}
{
"name": "Jane Doe",
"id": 23456,
"company": "Initrode",
"site": "HQ"
}
{
"name": "Fred Anderson",
"id": 56789,
"company": "Initrode",
"site": "Branch Office"
}
{
"name": "Bill Jones",
"id": 34567,
"company": "Initrode",
"site": "Branch Office"
}
{
"name": "Fred Johnson",
"id": 6543,
"company": "Inittech",
"site": "Main Office"
}
{
"name": "James Fredson",
"id": 9876,
"company": "Inittech",
"site": "Main Office"
}
{
"name": "Sally May",
"id": 5432,
"company": "Inittech",
"site": "Testing Station"
}
{
"name": "Jack James",
"id": 8765,
"company": "Inittech",
"site": "Testing Station"
}
Проблема:
Здесь много повторений. Помимо повторения внешних меток на каждой стадии конвейера, есть также повторение .site
и .personnel
во второй и третьей частях конвейера соответственно.
Мои реальные данные намного сложнее, поэтому это повторение еще хуже и его намного сложнее читать.
Кстати, вот неработающий код, который я пробовал ранее для той же цели выше:
jq '{company,site: .sites[].name,name: .sites[].personnel[].name,id: .sites[].personnel[].UID}' sample.json
Это намного меньше повторений, но, к сожалению, он возвращает каждого человека, связанного с каждым идентификатором и сайтом в их компании - неверные результаты, например, перекрестное объединение базы данных вместо внутреннего соединения.
Я не совсем знаю, как описать словами, что здесь нужно, но, надеюсь, приведенный выше пример поможет прояснить ситуацию.
Одним из способов описать это является то, что я пытаюсь объединить несколько пар имя-значение из массивов подобъектов в объект верхнего уровня, не возвращая вместе какие-либо комбинации пар имя-значение, взятые из различных подобъектов в одном и том же значении массива. Но это не совсем легко, даже для меня; отсюда приведенный выше пример ввода / вывода.
Просто для интереса, вот реальный рабочий код, который у меня есть, с обфусцированными именами атрибутов:
jq '.pears[]|{pear: .name,file: .somepath,toBeFiltered: (.appletypes[]|select(.name == "orange")|.bananas[]|{banana: .name,apples: .apples[]})}|{pear,file,banana: .toBeFiltered.banana,applestem: .toBeFiltered.apples.applestem,orangecomment: (.toBeFiltered.apples.peaches[]|select(.akey == "string")|.avalue.value),linenumber: (.toBeFiltered.apples.peaches[]|select(.akey == "string")|.line)}' realfile.json