How to pass bash array variable to jq not file

Viewed 522

I want to modify my json and add more fields

current JSON:

{
  "cubes": [
    {
      "no": 1,
      "plant_number": "1050-0"
    },
    {
      "no": 2,
      "plant_number": "2050-0"
    },
    {
      "no": 3,
      "plant_number": "3050-0"
    }
  ]
}

I want to add new field and output should look like

expected output:

{
  "no": 1,
  "plant_number": "1050-0",
  "1050-0":"1.1.1.1"
}
{
  "no": 2,
  "plant_number": "2050-0",
  "2050-0":"2.2.2.2"
}
{
  "no": 3,
  "plant_number": "3050-0",
  "3050-0":"3.3.3.3"
}

These IPs suppose to get extract by bash so I created script like

first try: I can add static ip like below

jq  '.cubes[]| {no,plant_number} | . + {(.plant_number): "0.0.0.0"} ' my.json 

It results in following JSON

{
  "no": 1,
  "plant_number": "1050-0",
  "1050-0","0.0.0.0"
}
{
  "no": 2,
  "plant_number": "2050-0",
  "2050-0":"0.0.0.0"
}
{
  "no": 3,
  "plant_number": "3050-0",
  "3050-0":"0.0.0.0"
}

second try:

# Here for sake of simplicity declaration is like this otherwise its function which return array
declare -a ips=('1.1.1.1' '2.2.2.2' '3.3.3.3');
jq  '.cubes[]| {no,plant_number} | . + {(.plant_number): $ips} ' my.json

its giving error

jq: 1 compile error

third try:

declare -a ips=('1.1.1.1' '2.2.2.2' '3.3.3.3');
jq  --arg ips $ips '.cubes[]| {no,plant_number} | . + {(.plant_number): $ips} ' my.json

This results in following

{
  "no": 1,
  "plant_number": "1050-0",
  "1050-0": "1.1.1.1 2.2.2.2 3.3.3.3"
}
{
  "no": 2,
  "plant_number": "2050-0",
  "2050-0": "1.1.1.1 2.2.2.2 3.3.3.3"
}
{
  "no": 3,
  "plant_number": "3050-0",
  "3050-0": "1.1.1.1 2.2.2.2 3.3.3.3"
}

How can I dynamically assign values to array?

1 Answers

You cannot (easily) pass an array from shell into an array in jq. But as you are dealing with (strictly formatted) IPs you can pass them as one string ("${ips[*]}") and split it into an array from within jq ($ips / " ").

declare -a ips=('1.1.1.1' '2.2.2.2' '3.3.3.3');
jq --arg ips "${ips[*]}" '
  [.cubes, $ips / " "] | transpose[] as [$c,$ip] | $c + {($c.plant_number): $ip}
' my.json
{
  "no": 1,
  "plant_number": "1050-0",
  "1050-0": "1.1.1.1"
}
{
  "no": 2,
  "plant_number": "2050-0",
  "2050-0": "2.2.2.2"
}
{
  "no": 3,
  "plant_number": "3050-0",
  "3050-0": "3.3.3.3"
}

Demo

Related