3
$ n="foo"; echo "{}" | jq --arg n "$n" '. += { "$n": $n }'
{
  "$n": "foo"
}

My reading of https://jqlang.github.io/jq/manual/#types-and-values suggests that this should work -- but clearly it doesn't. What's going on?

2 Answers 2

4

You can accomplish this by wrapping $n in parenthesis to tell jq to evaluate the expression:

n="foo"; echo "{}" | jq --arg n "$n" '. += { ($n): $n }'

Or probably better suited for this task would be jo(1):

$ jo "$n"="$n"
{"foo":"foo"}

I'm not sure if the documentation is just wrong or if my ability to comprehend is not at a high enough level but it does seem to say that your example should work:

Key expressions other than constant literals, identifiers, or variable references, need to be parenthesized, e.g., {("a"+"b"):59}.

And one might assume that is referring to a jq native variable rather than one injected by the shell as they are slightly different, but alas both need to be parenthesized:

$ echo '{}' | jq 'def myvar: "foo"; {myvar: myvar}'
{
  "myvar": "foo"
}
$ echo '{}' | jq 'def myvar: "foo"; {(myvar): myvar}'
{
  "foo": "foo"
}
5
  • Ta, adding brackets is what it needed. Never heard of jo -- looks like it could make thngs easier to construct an object then forward it via xargs to jq as a --jsonarg. Commented Oct 5, 2024 at 16:34
  • 1
    Or just jq -n --arg n foo '{($n): $n}'. Beware that jo syntax won't necessarily interpret all $n values as strings. Try with --help, 1 or [] for instance. Commented Oct 5, 2024 at 16:35
  • @StéphaneChazelas: Interesting that --help breaks it even when using --. 1 works for me and wouldn't [] as a key be invalid json anyway though? Commented Oct 5, 2024 at 17:18
  • 1
    Shorter with .[$n] = $n. Commented Oct 5, 2024 at 22:41
  • 1
    An object key can be any string, including "", "[]", "null", etc. jo -- -s "$n=$n" will help for n=--help or n=1, not for [], null, @x, a=b... jo's interface is severely broken by design IMO. Commented Oct 6, 2024 at 5:11
3

You can use:

$ n=foo
$ jq -cn --arg n "$n" '{$n:$n}'
{"foo":"foo"}

That is use the variable $n as the key, not the "$n" string. jq -n is like echo null | jq.

$ jq -cn --arg n "$n" '.[$n]=$n'
{"foo":"foo"}

Not using the {...} object constructor but assigning a value for a given key.

$ jq -cn --arg n "$n" '{"key\($n)":$n}'
{"keyfoo":"foo"}

Showing how to dereference a jq variable inside a string literal (in \(expr), expr can be any jq expression, not just a variable).

$ jq -cn --arg n "$n" '{("key"+$n):$n}'
{"keyfoo":"foo"}

In an object constructor, when keys are to be the result of a jq expression, they must be inside (...).

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.