jqを使用してオブジェクトの変数の値に基づいてオブジェクトを選択する


236

次のjsonファイルがあります。

{
    "FOO": {
        "name": "Donald",
        "location": "Stockholm"
    },
    "BAR": {
        "name": "Walt",
        "location": "Stockholm"
    },
    "BAZ": {
        "name": "Jack",
        "location": "Whereever"
    }
}

私はjqを使用しており、「場所」が「ストックホルム」であるオブジェクトの「名前」要素を取得したいと考えています。

私はすべての名前を取得できることを知っています

cat json | jq .[] | jq ."name"
"Jack"
"Walt"
"Donald"

しかし、サブキーの値(ここでは"location" : "Stockholm")を考えると、特定のオブジェクトのみを印刷する方法がわかりません。

回答:


341

jqを使用したJSONの処理に関するこの投稿を基に、次のselect(bool)ように使用できます。

$ jq '.[] | select(.location=="Stockholm")' json
{
  "location": "Stockholm",
  "name": "Walt"
}
{
  "location": "Stockholm",
  "name": "Donald"
}

30
親「FOO」、「BAR」、「BAZ」はどのようにして入手できますか?
spazm

184

名前だけのストリームを取得するには:

$ jq '.[] | select(.location=="Stockholm") | .name' json

生成する:

"Donald"
"Walt"

対応する(キー名、「名前」属性)ペアのストリームを取得するには、次のことを考慮してください。

$ jq -c 'to_entries[]
        | select (.value.location == "Stockholm")
        | [.key, .value.name]' json

出力:

["FOO","Donald"]
["BAR","Walt"]

彼は、場所に基づいて、オブジェクト全体を望んでいる:「私は、サブキーの値が与えられた、あるオブジェクトのみを印刷する方法を見つけ出すことはできません」
Foを。

2
選択後にパイプは必要ありません。$ jq '。[] | select(.location == "Stockholm")。name 'json
Deepak

nameキー変数の作成($1パラメーターとしてシェル関数を使用)は機能しませんtermux-contact-list |jq -r '.[] | select(.name=="$1")|.number'。のように呼んでいcool_fn Name1ます。ただし、これは機能します:termux-contact-list |jq -r '.[] | select(.name=="Name1")|.number'
Timo

ここではあなたはそれが可変の場合のようなソリューションです。
ティモ

27

同様の関連する質問がありました。元のオブジェクト形式を(FOO、BARなどのキー名を使用して)戻したい場合はどうなりますか?

Jqはto_entriesfrom_entriesオブジェクトとキーと値のペア配列間の変換を提供します。それとともに、map選択の周りに

これらの関数は、オブジェクトとキーと値のペアの配列の間で変換を行います。to_entriesにオブジェクトが渡された場合、入力のk:vエントリごとに、出力配列に{"key":k、 "value":v}が含まれます。

from_entriesは逆の変換を行い、with_entries(foo)はto_entries |の省略形です。map(foo)| from_entries。オブジェクトのすべてのキーと値に対して何らかの操作を行うのに役立ちます。from_entriesは、キー、キー、名前、名前、値、値をキーとして受け入れます。

jq15 < json 'to_entries | map(select(.value.location=="Stockholm")) | from_entries'

{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}

with_entries略記を使用すると、次のようになります。

jq15 < json 'with_entries(select(.value.location=="Stockholm"))'
{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}

1
私を悩ませ続けていることの1つは、を使用する場合with_entries()、通常.valueselect句でも使用することを覚えておく必要があることです。これは、to_entriesマクロが指定されたエントリを.keyおよびに変換するためです。これは.value、でも発生しwith_entriesます。
Jaakko
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.