Home > database >  jq command prints the json twice instead of only once
jq command prints the json twice instead of only once

Time:01-04

I need to set some new value using jq command in a JSON file. Here is an example of file.json

{
  
  "Balise1": true,
  "Balise2": true,
  "OtherThingEnabled": false,
  "proxySettings": {
    "port": 0
  },
  "mailSettings": {},
  "maxRunningActivitiesPerJob": 5,
  "maxRunningActivities": 5,
}

In order to set the proxySettings value I use the following command

jq --arg host "proxy.hub.gcp.url.com" --arg port "80" '.proxySettings = { host: $host, port: $port }' file.json

Instead of printing the modified version of file.json, it prints both original and modified version like that:

{
  
  "Balise1": true,
  "Balise2": true,
  "OtherThingEnabled": false,
  "proxySettings": {
    "port": 0
  },
  "mailSettings": {},
  "maxRunningActivitiesPerJob": 5,
  "maxRunningActivities": 5,
}
{
  
  "Balise1": true,
  "Balise2": true,
  "OtherThingEnabled": false,
  "proxySettings": {
    "host": "proxy.hub.gcp.url.com"
    "port": "80"
  },
  "mailSettings": {},
  "maxRunningActivitiesPerJob": 5,
  "maxRunningActivities": 5,
}

I was expecting to print only the modified version. How could I create a new JSON file only with the modified version?

CodePudding user response:

I found the issue. I my shell I was modifying 2 thing on the same command like this :

jq --arg host "proxy.hub.gcp.url.com" --arg port "80" '.proxySettings = { host: $host, port: $port }, .mailSettings = '{value1: "Value1"}' file.json

The command was printing the first change, then the second one. I had to create two seperate jq command.

CodePudding user response:

Comma , feeds the same input to two filters, therefore programs such ., . will output their input twice.

If two filters are separated by a comma, then the same input will be fed into both and the two filters' output value streams will be concatenated in order: first, all of the outputs produced by the left expression, and then all of the outputs produced by the right. For instance, filter .foo, .bar, produces both the "foo" fields and "bar" fields as separate outputs.

Demo:

echo '"foobar"' | jq 'length, length'
6
6

Instead, you want to combine both filters sequentially with the pipe filter |, since the plain assignment operator = outputs its modified input.

jq --arg host "proxy.hub.gcp.url.com" \
   --arg port "80" \
   '.proxySettings = { host: $host, port: $port } | .mailSettings = {value1: "Value1"}'

Your initial question didn't include the full jq program (so it was missing a proper minimal reproducible example!), only your self-answer included the crucial details.

  • Related