1. ホーム
  2. json

[解決済み] JQ:キーに対するフィルタリング

2022-02-15 22:10:38

質問

JQコマンドを使って、jsonオブジェクトにフィルタをかけ、選択的にキーを抽出しようとしています。 以下は、ファイルx.txtに配置したサンプルオブジェクトです。

{
  "activities" : {

    "-KSndgjqvmQkWVKHCpLh" : {
      "create_device" : "...",
      "stop_time_utc" : "2016-11-01T23:08:08Z"
    },

    "-KSoBSrBh6PZcjRocGD7" : {
      "create_device" : "..."
    },

    "-KSptboGjo8g4bieUbGM" : {
      "create_device" : "...",
      "stop_time_utc" : "2017-01-17T23:08:08Z"
    }

  }
}

以下のコマンドで、すべてのアクティビティキーを抽出することができます。

cat x.txt | jq '.activities | keys'
[
  "-KSndgjqvmQkWVKHCpLh",
  "-KSoBSrBh6PZcjRocGD7",
  "-KSptboGjo8g4bieUbGM"
]

私は、オブジェクトをフィルタリングしてstop_time_utc値を持つアクティビティエントリのみを選択し、有効期限が切れたアクティビティのみを選択するために"select(.stop_time_utc | fromdateiso8601 > now)" などを使って数時間ググって実験しています。例えば、フィルターを使用して、関連する1つのエントリのみを持つサンプルオブジェクトから配列を作成したいと思います。

[
  "-KSndgjqvmQkWVKHCpLh"
]

keysオプションで試すのは間違ったルートなのでしょうか? 何かアイデアや提案があれば、ぜひお願いします。

解決方法は?

with_entries/1 はあなたの味方です、例えば

.activities | with_entries( select(.value | has("stop_time_utc") ) )

を生成します。

{
  "-KSndgjqvmQkWVKHCpLh": {
    "create_device": "...",
    "stop_time_utc": "2016-11-01T23:08:08Z"
  },
  "-KSptboGjo8g4bieUbGM": {
    "create_device": "...",
    "stop_time_utc": "2017-01-17T23:08:08Z"
  }

これで、選択条件を追加したり、注目のキーネームを抽出したりすることが簡単にできるようになりました。 例えば

.activities
| with_entries( select( (.value.stop_time_utc? | fromdateiso8601?) < now ) )
| keys