仕事でJSONファイルをいじる事がおおくなり、jqコマンドのお世話になる事が多くなったのだが、そんな中で以下のような状況に出くわしたので備忘として残しておく。
例えば以下のファイルで、キー「id」の値が「test2」の場合のみ、「format」を「log」に書き換えたい場合。

● test.json

[
  {
    "id": "test1",
    "format": "zip",
    "size": 50
  },
  {
    "id": "test2",
    "format": "csv",
    "size": 100
  },
  {
    "id": "test3",
    "format": "txt",
    "size": 500
  },
  {
    "id": "test4",
    "format": "tar.gz",
    "size": 30
  },
  {
    "id": "test5",
    "format": "xls",
    "size": 6000
  }
]

そんな時は、以下のようにjqコマンドを実行すれば、指定した条件のキーの値を持つ配列に対してのみ、値の書き換えを行わせる事が出来る。

jq '(.[] | select(.条件となるキー名 == "キーの値") | 書き換えるキー名) |= "書き換え後のキーの値"' 対象のJSONファイル
[root@test-node ~]# cat /tmp/test.json
[
  {
    "id": "test1",
    "format": "zip",
    "size": 50
  },
  {
    "id": "test2",
    "format": "csv",
    "size": 100
  },
  {
    "id": "test3",
    "format": "txt",
    "size": 500
  },
  {
    "id": "test4",
    "format": "tar.gz",
    "size": 30
  },
  {
    "id": "test5",
    "format": "xls",
    "size": 6000
  }
]
[root@test-node ~]# jq '(.[] | select(.id == "test2") | .format) |= "log"' /tmp/test.json
[
  {
    "id": "test1",
    "format": "zip",
    "size": 50
  },
  {
    "id": "test2",
    "format": "log",
    "size": 100
  },
  {
    "id": "test3",
    "format": "txt",
    "size": 500
  },
  {
    "id": "test4",
    "format": "tar.gz",
    "size": 30
  },
  {
    "id": "test5",
    "format": "xls",
    "size": 6000
  }
]

特定のキーの値が指定した値よりも大きい場合に書き換える(今回の例の場合、「size」の値が300より大きい場合)の例がこちら。

[root@test-node ~]# jq '(.[] | select(.size > 300) | .format) |= "log"' /tmp/test.json
[
  {
    "id": "test1",
    "format": "zip",
    "size": 50
  },
  {
    "id": "test2",
    "format": "csv",
    "size": 100
  },
  {
    "id": "test3",
    "format": "log",
    "size": 500
  },
  {
    "id": "test4",
    "format": "tar.gz",
    "size": 30
  },
  {
    "id": "test5",
    "format": "log",
    "size": 6000
  }
]

なお、書き換えを行うキーとして新しい値を記述することで、特定の条件を持った配列に対してのみKey-Valueを追加させる事も出来る。

[root@test-node ~]# jq '(.[] | select(.id == "test2") | .aaa) |= "bbb"' /tmp/test.json
[
  {
    "id": "test1",
    "format": "zip",
    "size": 50
  },
  {
    "id": "test2",
    "format": "csv",
    "size": 100,
    "aaa": "bbb"
  },
  {
    "id": "test3",
    "format": "txt",
    "size": 500
  },
  {
    "id": "test4",
    "format": "tar.gz",
    "size": 30
  },
  {
    "id": "test5",
    "format": "xls",
    "size": 6000
  }
]