Home > Blockchain >  Construct json through jq tool in shell script loop
Construct json through jq tool in shell script loop

Time:10-17

json can be created using the following command.

  jq -n \
  --arg v1 "Value1" \
  --arg v2 "Value2" \
  '{k1: "$v1", k2:$v2'}

But when my key is mutable, how should I loop? For example, the script I execute is

test.sh k1=v1 k2=v2 k3=v3

test.sh is as follows

index=1
while ((index <= "$#")); do
  data_i_key=$(echo ${!index} | awk -F "=" '{print $1}')
  data_i_value=$(echo ${!index} | awk -F "=" '{print $2}')
  let index  
  JSON_STRING=$(jq -n \
    --arg value "$data_i_value" \
    '{'"$data_i_key"': $value'})
    echo $JSON_STRING

The above print result is

{ "K3": "V3" }

if I replace it with

JSON_STRING =$(jq -n \
    --arg val_value "$dataValue" \
    '{'"$data_i_key"': $val_value'})

The print result is

{ "k1": "v1" }{ "k2": "v2" }{ "K3": "V3" }

The above two methods have not achieved the goal, do you have a good way to deal with it? My desired output is

{ "k1": "v1" , "k2": "v2" ,"K3": "V3" }

hope you can help me.

CodePudding user response:

I'd suggest a totally different, but simpler, approach:

for kv; do
  echo "$kv" | jq -R './"=" | {key:first,value:last}'
done | jq -s 'from_entries'

It builds {key: …, value: …} objects from your positional parameters (splitting them by the equal sign) and then slurping all those objects in a second jq process, converting them into a single object via from_entries.

Alternatively, using -n (--null-input), --args and then accessing via $ARGS.positional. This avoids the loop and the second jq call altogether.

jq -n '$ARGS.positional | map(./"=" | {key:first,value:last}) | from_entries' --args "$@"

CodePudding user response:

Use parentheses around the key expression to have it evaluated:

jq -n --arg k1 "Key1" --arg v1 "Value1" '{($k1): $v1}'
{
  "Key1": "Value1"
}

CodePudding user response:

Perhaps this, which will handle an arbitrary number of key=value arguments:

#!/usr/bin/env bash

args=()
for arg; do
    IFS="=" read -r k v <<<"$arg"
    args =("$k" "$v")
done

jq -n --args '
    $ARGS.positional as $a
    | reduce range(0; $a | length; 2) as $i ({}; .[$a[$i]] = $a[$i   1])
' "${args[@]}"

Produces:

$ ./test.sh k1=v1 k2=v2 k3=v3
{
  "k1": "v1",
  "k2": "v2",
  "k3": "v3"
}
  • Related