web-dev-qa-db-ja.com

jqを使用して、dictの配列内の1つの値を更新します

Dictの値を更新したいのですが、dictの別の値でしか識別できません。つまり、次の入力が与えられます。

[
  {
    "format": "geojson",
    "id": "foo"
  },
  {
    "format": "geojson",
    "id": "bar"
  },
  {
    "format": "Zip",
    "id": "baz"
  }
]

bazの付随する形式を「csv」に変更したい:

[
  {
    "format": "geojson",
    "id": "foo"
  },
  {
    "format": "geojson",
    "id": "bar"
  },
  {
    "format": "csv",
    "id": "baz"
  }
]

私はこれが機能することを発見しました:

jq 'map(if .id=="baz" then .format="csv" else . end)' my.json

しかし、これはかなり冗長に見えるので、これを表現するためのよりエレガントな方法があるのではないかと思います。 jqには、ある種の式セレクターがないようです。これに相当するのは、xpathの[@id='baz']です。

(この質問を始めたとき、私は[.[] |...]を持っていましたが、mapを発見したので、思ったほど悪くはありません。)

14
Steve Bennett

複雑な割り当てはあなたが探しているものです:

jq '(.[] | select(.id == "baz") | .format) |= "csv"' my.json

おそらく短くはありませんが、要求に応じてよりエレガントです。ドキュメントの最後のセクションを参照してください: http://stedolan.github.io/jq/manual/#Assignment

編集:mapを使用:

jq 'map((select(.id == "baz") | .format) |= "csv")' my.json 
22
Hans Z.