2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【jq】配下に特定の文字列を持つオブジェクトを取得する

Posted at

はじめに

以下のJSONから、「配下に特定のメールアドレス(userA@example.com)を持つrequestParametersの一覧」を取得したかったので、調べてみました。

sample.json
[
  {
    "requestParameters": {
      "emailAddress": "userA@example.com"
    }
  },
  {
    "requestParameters": {
      "identities": [
        "userB@example.com",
        "userA@example.com"
      ]
    }
  },
  {
    "requestParameters": {
      "templateName": "templateNameC",
      "emailAddress": "userC@example.com"
    }
  }
]

具体的には、上のJSONを以下に整形します。

result.json
[
  {
    "requestParameters": {
      "emailAddress": "userA@example.com"
    }
  },
  {
    "requestParameters": {
      "identities": [
        "userB@example.com",
        "userA@example.com"
      ]
    }
  }
]

結論

こんな感じで取得できました。

$ cat sample.json | \
   jq '[.[] | select(.requestParameters[] | if type=="array" then .[] else . end | . == "userA@example.com")]'

[
  {
    "requestParameters": {
      "emailAddress": "userA@example.com"
    }
  },
  {
    "requestParameters": {
      "identities": [
        "userB@example.com",
        "userA@example.com"
      ]
    }
  }
]

詳細

上のフィルターに改行を入れると、以下のようになります。

$ cat sample.json | \
   jq '[
          .[] | select(
                .requestParameters[]
                  | if type=="array" then .[] else . end
                  | . == "userA@example.com"
              )
       ]'

順に見ていきます。

.requestParameters[]

配列の各要素を取得するのに使う[]ですが、オブジェクトに対しても使えます。
その場合、オブジェクトの全てのValueを取得できます。

jq Manualには以下のように記述されています。

You can also use this on an object, and it will return all the values of the object.

簡単な例.sh
$ echo '{"a": 1, "b": 2}' | jq '.[]'

1
2
今回の例.sh
$ cat sample.json | jq '.[].requestParameters[]'

"userA@example.com"
[
  "userB@example.com",
  "userA@example.com"
]
"templateNameC"
"userC@example.com"

if type=="array" then .[] else . end

よくあるif文です。
入力が配列(type=="array")であれば配列の各要素(.[])を返し、そうでなければ入力(.)を返します。

簡単な例.sh
$ echo [1,2] | jq 'if type=="array" then .[] else . end'
1
2

$ echo 1 | jq 'if type=="array" then .[] else . end'
1
今回の例.sh
$ cat sample.json | jq '.[].requestParameters[] | if type=="array" then .[] else . end'

"userA@example.com"
"userB@example.com"
"userA@example.com"
"templateNameC"
"userC@example.com"

. == "userA@example.com"

入力値が"userA@example.com"に一致するか確認する

簡単な例.sh
$ echo '["userA@example.com", "userB@example.com"]' \
   | jq '.[] | . == "userA@example.com"'
true
false
今回の例.sh
$ cat sample.json \
  | jq '.[].requestParameters[]
  | if type=="array" then .[] else . end
  | . == "userA@example.com"'

true
false
true
false
false

select(boolean_expression)

入力値に対して、式boolean_expressionがtrueを返す場合、その入力値をそのまま返却します。
trueを返さない場合は何も返しません。

簡単な例.sh
$ echo [1,5,3,0,7] | jq '.[] | select(. >= 5)'
5
7
今回の例.sh
$ cat sample.json | \
   jq '   .[] | select(
                .requestParameters[]
                  | if type=="array" then .[] else . end
                  | . == "userA@example.com"
              )'

{
  "requestParameters": {
    "emailAddress": "userA@example.com"
  }
}
{
  "requestParameters": {
    "identities": [
      "userB@example.com",
      "userA@example.com"
    ]
  }
}

参考:

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?