maria
maria

Reputation: 55

Update fields from string in JQ

I have a bash $string containing the values: abc,def and a file.json looking like this:

[
  {
    "loc": "51.12345, 12.12345",
    "city": "CityName1"
  },
  {
    "loc": "65.12345, 15.12345",
    "city": "CityName2"
  }
]

I'm trying to update the city field with the values from the string to get this result:

[
  {
    "loc": "51.12345, 12.12345",
    "city": "abc"
  },
  {
    "loc": "65.12345, 15.12345",
    "city": "def"
  }
]

I'm trying this code but it doesn't work, any suggestions?

  string="abc,def"; jq --arg variable "$string" '.city = $string' file.json

Upvotes: 3

Views: 121

Answers (3)

pmf
pmf

Reputation: 36086

Using reduce would be another way. Same lengths provided, it allows iterating over the entries along with their indices, which can then be used to access the input array.

string="abc,def"
jq --arg var "$string" '
  reduce ($var / "," | to_entries)[] as {$key, $value} (.;
    .[$key].city = $value
  )
'

I'm getting an error with jq version 1.4

To make this approach compatible with jq 1.4, replace the variable destructuring with a plain variable, and access its parts later, e.g.

string="abc,def"
jq --arg var "$string" '
  reduce ($var / "," | to_entries)[] as $item (.;
    .[$item.key].city = $item.value
  )
'

Output:

[
  {
    "loc": "51.12345, 12.12345",
    "city": "abc"
  },
  {
    "loc": "65.12345, 15.12345",
    "city": "def"
  }
]

Upvotes: 1

oguz ismail
oguz ismail

Reputation: 50760

You're looking for something like this:

$ string=abc,def
$ jq --arg cities "$string" '[., ($cities / ",")] | transpose | map(.[0] + {city: .[1]})' file.json
[
  {
    "loc": "51.12345, 12.12345",
    "city": "abc"
  },
  {
    "loc": "65.12345, 15.12345",
    "city": "def"
  }
]
$

Upvotes: 4

Gilles Quénot
Gilles Quénot

Reputation: 185161

With :

> var json =   [
...     {
...       "loc": "51.12345, 12.12345",
...       "city": "CityName1"
...     },
...     {
...       "loc": "65.12345, 15.12345",
...       "city": "CityName2"
...     }
...   ]
> var c = 0
> ["abc", "def"].forEach(n => json[c++].city = n)
> console.log(JSON.stringify(json, null, 4))
[
    {
        "loc": "51.12345, 12.12345",
        "city": "abc"
    },
    {
        "loc": "65.12345, 15.12345",
        "city": "def"
    }
]

From a script :

#!/bin/bash

node<<EOF | sponge file.json
var json = $(< file.json)
var c = 0;
["abc", "def"].forEach(n => json[c++].city = n)
console.log(JSON.stringify(json, null, 4))
EOF

output file:

[
    {
        "loc": "51.12345, 12.12345",
        "city": "abc"
    },
    {
        "loc": "65.12345, 15.12345",
        "city": "def"
    }
]

Upvotes: 1

Related Questions