简体   繁体   中英

Replacing key value pair with spaces using jq

I have a properties file and a json file. The property file holds the key value pairs which needs to be replaced in the json.

When the value has no spaces it works as expected, but when the value has spaces, the value is not replaced.

Script that replaces the values

#!bin/bash
echo hello

while read line;
do
#echo $line
key=$(echo "$line" |cut -d':' -f1)
#echo $part1
value=$(echo "$line" |cut -d':' -f2)
if [[ ! -z $value ]];
then
key="\"$key\""
value="\"$value\""
echo $key : $value
jq '.parameters |= map( if .name == '$key' then .default = '$value' else . end )' cam.json > cam1.json
mv cam1.json cam.json
fi
done < prop.properties

property file

git_con_type:something
git_host_fqdn:something again
git_user:something again again
git_user_password:something
git_repo:something
git_repo_user:
git_branch:

JSON file

{
"name": "${p:Instance_Name}",
  "parameters": [
    {
      "name": "git_con_type",
      "default": "",
      "immutable_after_create": false
    },
    {
      "name": "git_host_fqdn",
      "default": "hello",
      "immutable_after_create": false
    },
    {
      "name": "git_user",
      "default": "",
      "immutable_after_create": false
    },
    {
      "name": "git_user_password",
      "default": "Passw0rd",
      "immutable_after_create": false
    },
    {
      "name": "git_repo",
      "default": "lm",
      "immutable_after_create": false
    },
    {
      "name": "git_repo_user",
      "default": "-Life",
      "immutable_after_create": false
    },
    {
      "name": "git_branch",
      "default": "master",
      "immutable_after_create": false
    },
    {
      "name": "git_clone_dir",
      "default": "/opt/git",
      "immutable_after_create": false
    }
  ]
}

Error

jq: error: syntax error, unexpected $end, expecting QQSTRING_TEXT or QQSTRING_INTERP_START or QQSTRING_END (Unix shell quoting issues?) at , line 1: .parameters |= map( if .name == "git_host_fqdn" then .default = "something jq: error: Possibly unterminated 'if' statement at , line 1: .parameters |= map( if .name == "git_host_fqdn" then .default = "something jq: 2 compile errors

how can I make jq accept values with space? I have tried on jqplay with spaces and it works there, but not on the script.

It would be much better to pass $key and $value into jq as illustrated in the following (deliberately minimalist) tweak of your script:

#!/bin/bash

while read line
do
  key=$(echo "$line" |cut -d':' -f1)
  value=$(echo "$line" |cut -d':' -f2)
  if [[ ! -z "$value" ]]
  then
     jq --arg key "$key" --arg value "$value" '.parameters |= map( if .name == $key then .default = $value else . end )' cam.json > cam1.json
     mv cam1.json cam.json
fi
done < prop.properties

It would be still better to avoid the bash loop altogether and do everything with just one invocation of jq.

One-pass solution

The idea is to create a dictionary ($dict) of key-value pairs, which can easily be done using the builtin filter INDEX/1 :

INDEX(inputs | split(":") | select(.[1] | length > 0); .[0])
| map_values(.[1]) as $dict
| $cam
| .parameters |= map( $dict[.name] as $value | if $value then .default = $value else . end )

Invocation

With the above jq program in program.jq :

jq -n -R -f program.jq --argfile cam cam.json prop.properties > cam1.json && mv cam1.json cam.json

Or using sponge :

jq -n -R -f program.jq --argfile cam cam.json prop.properties | sponge cam.json

Note in particular the -n option, which is needed because program.jq uses inputs .

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