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

n="foo"; echo "{}" | jq --arg 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"
}
Answer from jesse_b on Stack Exchange
Discussions

Create object from array of keys and values
I've been banging my head against the wall for several hours on this and just can't seem to find a way to do this. I have an array of keys and an array of values, how can I generate an obje... More on github.com
🌐 github.com
5
January 23, 2015
json - Using jq to extract multiple fields and create a new object - Stack Overflow
I have this particular json object, [ { "userid" : "fe2e48b7-858b-4a0d-964a-efb8483a00c4", "lastupdateddate" : "84798000-13cd-11ea-8080-808080808080", "transactionid" : " More on stackoverflow.com
🌐 stackoverflow.com
linux - creating a nested json file from variables using jq - Unix & Linux Stack Exchange
However, since you have a nested structure, you may want to create that sub-structure in a separate call to jq as is shown by glenn jackman. ... jq -n \ --arg configId "$configid" \ --arg objectname tempfile \ --argjson artifacts "$( jq -n \ --arg name oer \ --arg version "$ot" \ '$ARGS.named' ... More on unix.stackexchange.com
🌐 unix.stackexchange.com
November 8, 2021
bash - Add JSON objects to array using jq - Unix & Linux Stack Exchange
My goal is to output a JSON object using jq on the output of a find command in bash. It could either be a one-line command or a bash script. I have this command which creates JSON objects from eac... More on unix.stackexchange.com
🌐 unix.stackexchange.com
February 26, 2020
🌐
Programming Historian
programminghistorian.org › en › lessons › json-and-jq
Reshaping JSON with jq | Programming Historian
May 24, 2016 - By wrapping . operators within either [] or {}, jq can synthesize new JSON arrays and objects. This can be useful if you want to output a new JSON file. As we will see below, this can also be a crucial intermediate step when reshaping complex JSON. Create a new set of JSON objects with the following filter:
🌐
Exercism
exercism.org › tracks › jq › concepts › objects
Objects in jq on Exercism
Re-using key-value pairs from an input object. $ jq -n '$ENV | {USER: .USER, EDITOR: .EDITOR}' { "USER": "glennj", "EDITOR": "vim" }
🌐
Qmacro
qmacro.org › blog › posts › 2022 › 05 › 06 › converting-strings-to-objects-with-jq
Converting strings to objects with jq - DJ Adams
May 6, 2022 - Similar to the array construction there's also the object construction, with which objects can be created on the fly quite easily. And as the manual says: If the keys are "identifier-like", then the quotes can be left off · So I can use name rather than "name" for the property, reducing the JSON noise a little: jq -R '[.,inputs] | map(sub("^.+/";"")) | map({name: .})' names.txt
🌐
jq
jqlang.org › manual
jq 1.8 Manual
This is useful when using jq as a simple calculator or to construct JSON data from scratch. ... Don't parse the input as JSON. Instead, each line of text is passed to the filter as a string. If combined with --slurp, then the entire input is passed to the filter as a single long string. ... Instead of running the filter for each JSON object in the input, read the entire input stream into a large array and run the filter just once.
🌐
GitHub
gist.github.com › joar › 776b7d176196592ed5d8
Add a field to an object with JQ · GitHub
$ echo '{"hello": "world"}' | jq --arg foo bar '. + {foo: ("not" + $foo)}' { "hello": "world", "foo": "notbar" } ... I have json which is an object containing a property that is an array, and I want to create another property with the same value as an existing property, without changing anything else.
Find elsewhere
🌐
GitHub
github.com › jqlang › jq › issues › 675
Create object from array of keys and values · Issue #675 · jqlang/jq
January 23, 2015 - I've been banging my head against the wall for several hours on this and just can't seem to find a way to do this. I have an array of keys and an array of values, how can I generate an object. Input: [["key1", "key2"], ["val1", "val2"]] ...
Author   amjibaly
🌐
DEV Community
dev.to › peter_meszaros_64a5a9137d › jq-build-json-at-bash-script-2h06
JQ - build JSON at bash script - DEV Community
May 16, 2023 - From time to time there is requirement build JSON object at bash script. This can be done in several ways. Depend on complexity of requirement. As first attemption came up to write exact JSON to variable, something like this · #!/usr/bin/env bash JSON=$(cat <<-END { "what":"something", "when":"now" } END ) echo "$JSON" ... #!/usr/bin/env bash WHAT="something" WHEN="now" JSON=$(jq -n \ --arg what "$WHAT" \ --arg when "$WHEN" \ '$ARGS.named' ) echo "$JSON"
Top answer
1 of 2
3

Assuming a ticket is to be generated for each object entry:

{tickets: [
  .objectEntries[]
  | [.attributes[]
    | [.objectTypeAttributeId,
      (.objectAttributeValues | map(.displayValue))] as [$id, $val]
    |   if $id == 328 then {ticketId:  $val[0]}
      elif $id == 329 then {hostnames: $val}
      elif $id == 330 then {date:      $val[0]}
      else empty end
  ] | add
]}

Online demo

2 of 2
0

Here we go, it's not pretty, there may be a better solution but it works: https://jqplay.org/s/sxussfa2Vj

.objectEntries | {tickets: map(.attributes | 
{ticketID: (reduce .[] as $r (null;  if $r.objectTypeAttributeId == 328 
then $r.objectAttributeValues[0].value else . end)),
date: (reduce .[] as $r (null;  if $r.objectTypeAttributeId == 330
then $r.objectAttributeValues[0].value else . end)), 
hostnames: (reduce .[] as $r ([];  if $r.objectTypeAttributeId == 329 
then $r.objectAttributeValues | map(.value) else . end))})}

There's a lot of unpacking and repacking going on here that sort of distracts from the core. You have an array of tickets (aka entries), and over those we map. The various properties we have to grab from different entries of an array, which is done using reduce. Reduce goes through the array of objects and picks out the right one and keeps track of the value.

Maybe there's a nice way, but this works already, so you can play with it further, trying to simplify.

Your original solution almost works, you did a good job there, just needed a map:

.objectEntries[].attributes | 
{ticketid: . | map(select(.objectTypeAttributeId == 328))[0] | 
.objectAttributeValues[0].displayValue, 
date: . | map(select(.objectTypeAttributeId == 330))[0] |
.objectAttributeValues[0].displayValue, 
hostnames: . | map(select(.objectTypeAttributeId == 329))[0] | 
[.objectAttributeValues[].displayValue]}

Try it out, it even works with multiple tickets ;) https://jqplay.org/s/ydoCgv9vsI

🌐
Atomic Spin
spin.atomicobject.com › jq-creating-updating-json
How to Use jq for Creating and Updating JSON Data
November 25, 2024 - Here are some examples of using the jq command-line utility to create new JSON data from scratch or update values in an existing JSON document.
🌐
Petermekhaeil
petermekhaeil.com › til › jq-append-json
Add an object to existing JSON using jq
# Optional: Create new JSON file `feed.json` with empy array. jq -n '[]' > feed.json # Append an object to the array from `feed.json` # and store the new JSON in `feed.json.tmp` jq \ --arg date "$date" \ --arg title "$title" \ '. += [{"date": $date, "title": $title}]' \ feed.json > feed.json.tmp # Replace temp file with original file.
🌐
DigitalOcean
digitalocean.com › community › tutorials › how-to-transform-json-data-with-jq
How To Transform JSON Data with jq | DigitalOcean
September 23, 2025 - You’ll combine these filters into one jq command that does all of the work. You will create a new JSON object that merges the three filters in order to create a new data structure that displays the information you desire.
Top answer
1 of 2
1

Elements of a stream are processed independently. So we have to change the input.

We could group the stream elements into an array. For an input stream, this can be achieved using --slurp/-s.[1]

jq -s '
   ( .[0].Columns[0] | map_values( tostring ) ) as $map |
   (
      .[0],
      (
         .[1:][] |
         .Users[] |= with_entries(
            .key = $map[ .key ]
         )
      )
   )
'

Demo on jqplay

Alternatively, we could use --null-input/-n in conjunction with input and/or inputs to read the input.

jq -n '
   input |
   ( .Columns[0] | map_values( tostring ) ) as $map |
   (
      .,
      (
         inputs |
         .Users[] |= with_entries(
            .key = $map[ .key ]
         )
      )
   )
'

Demo on jqplay

Note that your desired output isn't valid JSON. Object keys must be strings. So the above produces a slightly different document than requested.

Note that I assumed that .Columns is always an array of one exactly one element. This is a nonsense assumption, but it's the only way the question makes sense.


  1. For a stream the code generates, you could place the stream generator in an array constructor ([]). reduce can also be used to collect from a stream. For example, map( ... ) can be written as [ .[] | ... ] and as reduce .[] as $_ ( []; . + [ $_ | ... ] ).
2 of 2
1

The following has the merit of simplicity, though it does not sort the keys. It assumes jq is invoked with the -n option and of course produces a stream of valid JSON objects:

input
| . as $Columns
| .Columns[0] as $dict
| input # Users
| .Users[] |= with_entries(.key |= ($dict[.]|tostring))
| $Columns, .

If having the keys sorted is important, then you could easily add suitable code to do that; alternatively, if you don't mind having the keys of all objects sorted, you could use the -S command-line option.