Вопрос или проблема
Я хочу вывести конкретный ключ списка из списка хешей в виде строк, где каждый элемент внешнего массива разделён пустой строкой. Чтобы проиллюстрировать:
Входные данные:
[
[
{
"visible": true,
"url": "url-1"
},
{
"visible": false,
"url": "url-2"
}
],
[
{
"visible": true,
"url": "url-a"
},
{
"visible": false,
"url": "url-b"
}
]
]
Ожидаемый вывод:
url-1
url-2
url-a
url-b
Теперь я могу получить желаемый вывод, используя следующее:
cat input.txt | jq 'walk(if type == "object" then (.url | select( . != null)) end) | .[] | select(length > 0)' | jq 'join("\n")' | jq -rs 'join("\n\n")'
Здесь есть две проблемы:
- Получение значения конкретного ключа, не разрушая иерархию и обрабатывая потенциальные нулевые значения (поскольку ключ не существует или на самом деле был
null
), все это обрабатывается первой вызовомjq
, так что мы получаем список из списка строк. - Второй и третий вызов превращают это в желаемый вывод, список (сырых) строк, где каждый URL занимает свою строку, и разные записи внешнего массива разделены пустой строкой.
Но, похоже, должно быть более простое решение для каждой из этих проблем, особенно для второй.
Ответ или решение
Для решения задачи извлечения значений ключа из списка списков объектов в JSON формате с использованием инструмента jq
, можно упростить приведенный вами скрипт, обеспечив тем не менее соответствие всем требованиям. Входные данные представляют собой JSON-структуру, где каждый элемент является массивом объектов, содержащих, среди прочего, ключи visible
и url
. Необходимо извлечь значения по ключу url
для каждого объекта и получить их на выходе в виде строк, отделенных пустой строкой между разными группами.
Можно использовать однократный вызов jq
с некоторыми оптимизациями для большей читаемости и простоты. Вот пошаговая инструкция и предоставленный код для выполнения этой задачи.
Пример входных данных
Ваши входные данные выглядят следующим образом:
[
[
{
"visible": true,
"url": "url-1"
},
{
"visible": false,
"url": "url-2"
}
],
[
{
"visible": true,
"url": "url-a"
},
{
"visible": false,
"url": "url-b"
}
]
]
Решение с использованием jq
Вместо множества последовательных вызовов можно использовать следующую команду jq
:
cat input.txt | jq -r '.[][] | .url // empty' | awk 'NF {print; print ""}'
Объяснение команд
-
jq -r '.[][] | .url // empty'
:.[][]
— этот оператор позволяет обращаться к каждому элементу в каждом вложенном массиве, предоставляя доступ ко всем объектам..url // empty
— если ключurl
отсутствует или равенnull
, команда вернет пустое значение (ничто), что помогает избежать ошибок.
-
awk 'NF {print; print ""}'
:NF
— число полей в строке (если строка не пустая).{print; print ""}
— если строка не пустая, то сначала печатаем значение, а затем добавляем пустую строку.
Таким образом, результат будет выводить все URL в нужном формате:
url-1
url-2
url-a
url-b
Заключение
Предложенное решение упрощает ваш запрос, уменьшая количество вызовов jq
и добавляя обработку для потенциально отсутствующих или пустых значений. Практическое применение awk
в конце позволяет легко разделить группы значений пустыми строками. Это подход обеспечивает чистый и эффективный способ обработки сложных структур JSON и получения требуемого результата.