Jq - Как напечатать родительское значение объекта, когда я уже глубоко погружаюсь в объект?

Скажем, у меня есть следующий JSON, хранящийся в моей переменной jsonVariable.

{
    "id": 1,
    "details": {
        "username": "jamesbrown",
        "name": "James Brown"
    }
}

Я анализирую этот JSON с jq, используя следующее:

echo $jsonVariable | jq '.details.name | select(.name == "James Brown")'

Это даст мне выход

Джеймс Браун

Но что, если я тоже хочу получить удостоверение личности этого человека? Теперь я знаю, что это грубый и простой пример - программа, с которой я сейчас работаю, имеет глубину 5 или 6 уровней со многими различными функциями JQ, кроме select. Мне нужен способ выбрать родительское поле, когда я уже 5 или 6 слоев глубиной после выполнения различных методов фильтрации.

Кто-нибудь может помочь? Есть ли какой-нибудь способ "вернуться" назад к родителю? (Не уверен, что я имею смысл!)

Ответ 1

Для более общего подхода сохраните значение "родительского" элемента на нужном уровне детализации, затем проведите его в конце вашего фильтра:

jq '. as $parent | .details.name | select(. == "James Brown") | $parent'

Конечно, для тривиального случая, который вы раскрываете, вы можете полностью опустить это:

jq 'select(.details.name == "James Brown")'

Также учтите, что если ваши фильтры выбора возвращают много совпадений для одного родительского объекта, вы получите копию родительского объекта для каждого совпадения. Вы можете захотеть убедиться, что выбранные фильтры возвращают только один элемент на родительском уровне, обертывая все соответствия ниже родительского уровня в массив или дедуплицируя окончательный результат с помощью unique.

Ответ 2

Сделайте снимок:

echo $jsonVariable | jq '{Name: .details.name, Id: .Id}  | select(.name == "James Brown")'

Ответ 3

Вместо того, чтобы запрашивать значение, которое вы тестируете, запросите до корневого объекта, который содержит запрашиваемое значение, и значения, которые вы хотите выбрать.

Вам нужен объект, который содержит как id, так и name.

$ jq --arg name 'James Brown' 'select(.details.name == $name).id' input.json

Ответ 4

альтернативно, jtc позволяет легко найти решение - обращение к родителю (parent of parent и т.д.) происходит внутри пути, который вы строите:

bash $ echo $jsonVariable | jtc -w'<James Brown> [-2] [id]'
1
bash $