web-dev-qa-db-ja.com

jq-オブジェクトの子の深いところにいるときに、オブジェクトの親の値を出力するにはどうすればよいですか?

変数jsonVariableに保存されている次のJSONがあるとします。

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

以下を使用して、このJSONをjqで解析します。

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

これは私に出力を与えるでしょう

ジェームスブラウン

しかし、この人のIDも取得したい場合はどうなりますか?さて、これは大まかで単純な例であることを認識しています。現在作業しているプログラムは5レベルまたは6レベルの深さで、select以外のさまざまなJQ関数があります。さまざまなフィルタリング方法を実行した後、すでに5層または6層の深さにある場合、親のフィールドを選択する方法が必要です。

誰か助けてもらえますか?親に戻って「逆に行く」方法はありますか? (私が意味を成しているかどうかわかりません!)

28
x3nr0s

より一般的な方法として、必要な詳細レベルで「親」要素の値を保存し、それをフィルターの最後にパイプします。

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

もちろん、公開する些細なケースでは、これを完全に省略することができます。

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

また、選択したフィルターが1つの親オブジェクトに対して多くの一致を返す場合、一致ごとに親オブジェクトのコピーを受け取ることを考慮してください。親レベル以下のすべての一致を配列にラップするか、uniqueで最終結果を重複排除することにより、選択フィルターが親レベルで1つの要素のみを返すようにすることができます。

34
user3899165

テストする値までクエリを実行するのではなく、クエリを実行する値と選択する値を含むルートオブジェクトまでクエリを実行します。

idnameの両方を含むオブジェクトが必要です。

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

これを試してください:

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