skip to Main Content

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

3

Answers


  1. 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"
        }
    ]
    
    Login or Signup to reply.
  2. 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"
      }
    ]
    $
    
    Login or Signup to reply.
  3. 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"
      }
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search