Home > OS >  How to pass bash array variable to jq not file
How to pass bash array variable to jq not file

Time:12-15

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?

CodePudding user response:

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