简体   繁体   中英

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

You can use the map() function:

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

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

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM