x3nr0s
x3nr0s

Reputation: 2158

Bash and jq - Find a key contained in a variable and change it's value

Let's say I have the following json.

{
    "userid":334,

    "Parameters": [ 
        {
            "ParameterValue": "james", "ParameterKey": "name" 
        },
        {
            "ParameterValue": "22", "ParameterKey": "age" 
        },
        {
            "ParameterValue": "belfast", "ParameterKey": "city" 
        },
        {
            "ParameterValue": "software", "ParameterKey": "career" 
        }
    ]
}

I have some code which takes the JSON and extracts all of the keys and their values.

echo $my_json | jq -r '.Parameters[] | .ParameterKey + "=" + .ParameterValue' >> $OUTPUT_FILE 

If I look in my output file I have something similar to this:

name=james
age=22
city=belfast
career=software

How can I find, say "career" and change it's value before it is placed in the $OUTPUT_FILE? Example below:

name=james
age=22
city=belfast
career=consultation

Upvotes: 2

Views: 1772

Answers (3)

jq170727
jq170727

Reputation: 14725

Here is a solution which uses a generalization of from_entries to convert the data to an intermediate object, object multiplication with * to update the desired keys and a function to format the output taking into account blank values.

First we assume jq will be invoked with the --argjson parameter as follows to specify the key to be replaced:

$ jq -Mr --argjson replace '{"career":"consultation"}' -f filter.jq data.json

where data.json contains the sample data and filter.jq contains the following filter:

def from_entries(k;v): map({(k):v})|add;
def format_output:     keys[] as $k | if .[$k]!="" then "\($k)=\(.[$k])" else "#\($k)=" end;

  .Parameters
| from_entries(.ParameterKey;.ParameterValue)
| . * $replace
| format_output

Sample output:

age=22
career=consultation
city=belfast
name=james

If instead we run it as

$ jq -Mr --argjson replace '{"career":""}' -f filter.jq data.json

The output is

age=22
#career=
city=belfast
name=james

Try it online!

Upvotes: 1

RomanPerekhrest
RomanPerekhrest

Reputation: 92894

jq solution:

echo $my_json | jq -r --arg career "consultation" '.Parameters[] 
     | [.ParameterKey, if (.ParameterKey == "career") then $career else .ParameterValue end] 
     | join("=")' > outputfile
  • --arg career "consultation" - passing value "consultation" into jq script as a predefined variable named $career

  • join("=") - join/implode key and value using = as separator


The outputfile contents:

name=james
age=22
city=belfast
career=consultation

Upvotes: 2

hek2mgl
hek2mgl

Reputation: 158210

You can use the map() function:

jq -r '.Parameters | map(
           if .ParameterKey == "career" then (.ParameterValue = "foo") else . end)
       [] |  .ParameterKey + "=" + .ParameterValue'

Upvotes: 2

Related Questions