Reputation: 1262
I have a json file containing several profiles:
{
"profile1": {
"user": "user1",
"channel": "channel1",
"hook": "hook1"
},
"default": {
"user": "user1",
"channel": "channel1",
"hook": "hook2"
}
}
I want to use jq to insert another profile, "test", so that the end result will be
{
"profile1": {
"user": "user1",
"channel": "channel1",
"hook": "hook1"
},
"default": {
"user": "user1",
"channel": "channel1",
"hook": "hook2"
},
"test": {
"user": "user3",
"channel": "channel3",
"hook": "hook3"
}
}
Directly in the command line I can do it with:
cat filename |
jq '.+ { "test": { "user": "u3", "channel" : "c3", "hook": "w3" } }'
But when I try it in my bash script:
cat "$CONF_FILE" |
jq --arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH" \
'.+ { $p: { "user": $u, "channel": $c, "hook": $w } }' `
I'm getting the following error:
jq: error: syntax error, unexpected ':', expecting '}' (Unix shell quoting issues?) at <top-level>, line 1:
.+ { $p: { "user": $u, "channel": $c, "hook": $w } }
jq: error: syntax error, unexpected '}', expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
.+ { $p: { "user": $u, "channel": $c, "hook": $w } }
jq: 2 compile errors
I've tried surrounding the variable with quotes but then I get just the string $p:
cat "$CONF_FILE" |
jq --arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH" \
'.+ { "$p": { "user": $u, "channel": $c, "hook": $w } }'
result:
{
"profile1": {
"user": "user1",
"channel": "channel1",
"hook": "hook1"
},
"default": {
"user": "user1",
"channel": "channel1",
"hook": "hook2"
},
"$p": {
"user": "user3",
"channel": "channel3",
"hook": "hook3"
}
}
EDIT: I have found what seems a temporary solution, converting the object to an array, editing the value (now the profile name is a value and not a key) and converting the array back to an object:
cat "$CONF_FILE" |
jq --arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH" \
'to_entries | .+ [ { "key": $p, "value": { "user": $u, "channel": $c, "hook": $w } } ] | from_entries'
It seems crude, but it works. I am still hoping for a better solution...
Upvotes: 2
Views: 6771
Reputation: 14715
Here is a script that demonstrates a solution using env to access variables passed via the environment:
#!/bin/bash
CONF_FILE=data.json
export P=test
export U=user3
export C=channel3
export W=hook3
jq '
.[env.P] = {
user: env.U,
channel: env.C,
hook: env.W
}
' "$CONF_FILE"
If data.json
contains the sample data this script should produce the output
{
"profile1": {
"user": "user1",
"channel": "channel1",
"hook": "hook1"
},
"default": {
"user": "user1",
"channel": "channel1",
"hook": "hook2"
},
"test": {
"user": "user3",
"channel": "channel3",
"hook": "hook3"
}
}
Upvotes: 4
Reputation:
Use parenthesis around dynamic keys:
jq --arg p "$PROFILE" --arg u "$U" --arg c "$C" --arg w "$WH" \
'. + {($p): {"user": $u, "channel": $c, "hook": $w}}' "$CONF_FILE"
Upvotes: 6