jq compilation error for two maps - not replacing json value


I am observing an error with the following data when using two jq maps within a shell script.

test.json

[
  {
     "ParameterKey": "<ans1>",
     "ParameterValue": "<ans2>"
  }
]

My script is

cat test.json | \
jq 'map(if .ParameterKey == "<ans1>" then . + {"ParameterKey" : "input1" } else . end )' \
   'map(if .ParameterValue == "<ans2>" then . + {"ParameterValue" : "input2" } else . end)' \ 
> result.json


Although the precise error isn't given, running the command generates

jq: error: Could not open file map(if .ParameterValue == "<ans2>" 
then . + {"ParameterValue": "input2"} else . end): No such file or directory

The No such file or directory message indicates jq is trying to open a file named "map(if .ParameterValue == "<ans2>" then . + {"ParameterValue": "input2"} else . end)" which is happening because that string appears where jq expects the name of an input file.

To correct this you can combine the two filter strings into one string with | and pass test.json as the input file, e.g.

jq '
   map(if .ParameterKey == "<ans1>" then . + {"ParameterKey": "input1"} else . end)
 | map(if .ParameterValue == "<ans2>" then . + {"ParameterValue": "input2"} else . end)
' test.json > result.json

or keep your basic structure and add a second explicit jq invocation e.g.

cat test.json | \
jq 'map(if .ParameterKey == "<ans1>" then . + {"ParameterKey": "input1"} else . end)' | \
jq 'map(if .ParameterValue == "<ans2>" then . + {"ParameterValue": "input2"} else . end)' \
> result.json

In this particular case either will work but the first way is more efficient. Peak's suggestion which uses only a single map() is better still.


Here are two solutions - one that is both simple and brief, and one that scales well. Notice that in both cases, map is only needed once.

Simple and brief

map( if .ParameterKey   == "<ans1>" then . + {"ParameterKey":   "input1"} else . end
   | if .ParameterValue == "<ans2>" then . + {"ParameterValue": "input2"} else . end)

With a helper function

def maybe_update($key; $old; $new):
  if .[$key] == $old then .[$key] = $new else . end;

map( maybe_update("ParameterKey";   "<ans1>"; "input1")
   | maybe_update("ParameterValue"; "<ans2>"; "input2") )