Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update one value in array of dicts, using jq

Tags:

json

jq

I want to update a value in a dict, which I can only identify by another value in the dict. That is, given this input:

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

I want to change baz's accompanying format to 'csv':

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

I have found that this works:

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

But this seems rather verbose, so I wonder if there is a more elegant way to express this. jq seems to be missing some kind of expression selector, the equivalent of might be [@id='baz'] in xpath.

(When I started this question, I had [.[] |...], then I discovered map, so it's not quite as bad as I thought.)

like image 388
Steve Bennett Avatar asked Apr 21 '15 12:04

Steve Bennett


People also ask

How to update the values of a list of dictionaries in Python?

In this article, we will update the values of a list of dictionaries. The append function is used to insert a new value in the list of dictionaries, we will use pop () function along with this to eliminate the duplicate data. This function is used to insert updated data based on an index.

How to update the value of a nested dictionary to 7?

If you want to update the value of ‘b’ to 7, you can write as d ['b']=7. However the same method cannot be applied to nested ones. That will create a new key as the keys in outer dictionary will only be searched while you try to update. For example, see the code below:

What is JQ and how do I use it?

In the example above, we created new JSON from scratch. jq is equally useful for updating existing JSON data. In this example, we’ll start with a JSON object that defines a command to be executed and any environment variables that should be set when the command is run:

What are the JQ arguments when running JQ?

When running jq, the following arguments may become handy: Output the jq version and exit with zero. Output the fields of each object with the keys in sorted order.


1 Answers

A complex assignment is what you're looking for:

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

Perhaps not shorter but it is more elegant, as requested. See the last section of the docs at: http://stedolan.github.io/jq/manual/#Assignment

Edit: using map:

jq 'map((select(.id == "baz") | .format) |= "csv")' my.json 
like image 73
Hans Z. Avatar answered Oct 01 '22 12:10

Hans Z.