It seems to me that you want to output the two values (VolumeId and Tags[].Value) on the same line?

If that's the case, then a simple string concatenation should be enough:

$ jq -r '.Volumes[] | .VolumeId + " " + .Tags[].Value' volumes.json
vol-00112233 vol-rescue-system
vol-00112234 vol-rescue-swap
vol-00112235 vol-rescue-storage

The above can then be used in a pipeline with while-read:

jq -r '.Volumes[] | .VolumeId + " " + .Tags[].Value' volumes.json \
| while read -r volumeId tagValue; do
  other_command "$volumeId" "$tagValue"
done

You should note that if there is more than one element in Tags the result will reflect that. This can however be avoided by referring the first element in Tags: .Tags[0].Value

Answer from Andreas Louv on Stack Overflow
Top answer
1 of 2
4
$ jq -r '[ .[].list1[] ] | join(" ")' file
val1 val2 val3 val4 val5 val6

Create a new array with all the elements of each list1 array from each top-level key. Then, join its elements with spaces. This would give you the values in the order they occur in the input file.

An alternative (and arguably neater) approach is with map(.list1) which returns an array of arrays that you may flatten and join up:

$ jq -r 'map(.list1) | flatten | join(" ")' file
val1 val2 val3 val4 val5 val6

Your attempt generates one joined string per top-level key due to .list being one of the list1 arrays in turn. Your approach would work if you encapsulated everything up to the last pipe symbol in a [ ... ] (and expand the .list with .list[]) to generate a single array that you then join. This is what I do in my first approach above; only I use a slightly shorter expression to generate the elements of that array.

$ jq -r '[ to_entries[] |  { list: .value.list1 } | .list[] ] | join(" ")' file
val1 val2 val3 val4 val5 val6
2 of 2
0

Using Raku (formerly known as Perl_6)

~$ raku -MJSON::Tiny -e 'my %hash = from-json($_) given lines;  
                         my @a = %hash.values.map({ $_.values if $_{"list1"} }); 
                         .say for @a.sort.join(" ");'  file

OR:

~$ raku -MJSON::Tiny -e 'my  %hash = from-json($_) given lines; 
                         for %hash.values.sort() { print .values.sort ~ " " if $_{"list1"} };
                         put "";'  file

Raku is a programming language in the Perl-family that provides high-level support for Unicode. Like Perl, Raku has associative arrays (hashes and/or maps) built-in. The above code is admittedly rather verbose (first example), but you should be able to get the flavor of the language from both examples above:

  • Raku's community-supported JSON::Tiny is called at the command line,
  • All lines are given as one data element to the from-json function, which decodes the input and stores it in %hash,
  • First Example: Using a map, the values of the hash are searched through for "list1" keys. If (if) found, these are stored in the @a array. Then the @a array is printed.
  • Second Example: the %hash is iterated through using for, searched through for "list1" keys, and if found the associated values are printed (with at end-of-line). A final put call adds a newline.

Sample Input (includes bogus "list2" elements)

{
    "key1": {
        "list1": [
            "val1",
            "val2",
            "val3"
        ]
    },
    "key2": {
        "list1": [
            "val4",
            "val5"
        ]
    },
    "key3": {
        "list1": [
            "val6"
        ]
    },
    "key4": {
        "list2": [
            "val7"
        ]
    }
}

Sample Output:

val1 val2 val3 val4 val5 val6

Finally, in any programming solution it is often instructive to look at intermediate data-structures. So here's what the %hash looks like after decoding JSON input:

~$ raku -MJSON::Tiny -e 'my %hash = from-json($_) given lines;  .say for %hash.sort;'  file
key1 => {list1 => [val1 val2 val3]}
key2 => {list1 => [val4 val5]}
key3 => {list1 => [val6]}
key4 => {list2 => [val7]}

https://raku.land/cpan:MORITZ/JSON::Tiny
https://docs.raku.org/language/hashmap
https://raku.org

Discussions

Using jq to parse and display multiple fields in a json serially - Stack Overflow
A little bit more steps but I noticed ... for array so you need to construct one. To eliminate double quotes, use -r: echo $JSON | jq -r '.users[] | [.first,.last] | join(" ")' , means applying filter to the previous step's output with such order, so you .first then you get .last and ... More on stackoverflow.com
🌐 stackoverflow.com
jq select multiple elements from an array - Unix & Linux Stack Exchange
Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers · Stack Overflow for Teams is now called Stack Internal. Bring the best of human thought and AI ... More on unix.stackexchange.com
🌐 unix.stackexchange.com
November 27, 2024
How to search and replace multiple values in an array using jq? - Unix & Linux Stack Exchange
What would you want to input to ... (an array of) JSON objects like { name: "John", phone: "4321" }, so that one could find the correct name and new number from that? Would it be ok to do this in a simple loop, processing one entry at a time, or would you want to insist on doing everything in one invocation of jq? ... I don't need to replace n values, just these ... More on unix.stackexchange.com
🌐 unix.stackexchange.com
August 24, 2021
How do I select multiple keys for output?
This seems like a basic question but I can't find examples anywhere in the documentation. If I have input like - alpha: 1 beta: foo gamma: 0.3 delta: bar - alpha: 2 beta: baz gamma: 1.23 delta: buz... More on github.com
🌐 github.com
15
2
December 10, 2023
🌐
jq
jqlang.org › manual
jq 1.8 Manual
The ordering for objects is a little ... keys (as arrays in sorted order), and if their keys are equal then the values are compared key by key. sort_by may be used to sort by a particular field of an object, or by applying any jq filter. sort_by(f) compares two elements by comparing the result of f on each element. When f produces multiple values, it ...
🌐
Baeldung
baeldung.com › home › scripting › printing values in one line using the jq command
Printing Values in One Line Using the jq Command | Baeldung on Linux
March 18, 2024 - Using the jq command with the -r option and an appropriate filter expression, we can easily print the JSON data on a single line. In order to extract a single value from all the objects of a JSON array, we can use the map function of the jq command.
Top answer
1 of 2
14

To change one entry, make sure that the left-hand side of the assignment operator is a path in the original document:

jq --arg name John --arg phone 4321 \
    '( .contacts[] | select(.name == $name) ).phone = $phone' file

You can't use .contacts[] | select(.name == "John") | .phone |= ... since the select() extracts a set of elements from the contacts array. You would therefore only change the elements you extract, separately from the main part of the document.

Notice the difference in

( ... | select(...) ).phone = ...
^^^^^^^^^^^^^^^^^^^^^
path in original document

which works, and

... | select(...) | .phone = ...
      ^^^^^^^^^^^
      extracted bits

which doesn't work.


Using a loop for more than one entry, assuming e.g. bash:

names=( John Jane )
phones=( 4321 4321 )

tmpfile=$(mktemp)

for i in "${!names[@]}"; do
    name=${names[i]}
    phone=${phones[i]}

    jq --arg name "$name" --arg phone "$phone" \
        '( .contacts[] | select(.name == $name) ).phone = $phone' file >"$tmpfile"
    mv -- "$tmpfile" file
done

That is, I put the names in one array and the new numbers in another, then loop over the indexes and update file for each entry that needs changing, using a temporary file an intermediate storage.

Or, with an associative array:

declare -A lookup

lookup=( [John]=4321 [Jane]=4321 )

for name in "${!lookup[@]}"; do
    phone=${lookup[$name]}

    # jq as above
done

Assuming you have some JSON input document with the new phone numbers, such as

{
   "John": 1234,
   "Jane": 5678
}

which you can create using

jo John=1234 Jane=5678

Then you can update the numbers in a single jq invocation:

jo John=1234 Jane=5678 |
jq --slurpfile new /dev/stdin \
    '.contacts |= map(.phone = ($new[][.name] // .phone))' file

This reads our input JSON with the new numbers in a structure, $new, that looks like

[
  {
    "John": 1234,
    "Jane": 5678
  }
]

This is used in the map() call to change the phone numbers of any contact that is listed. The // .phone makes sure that if the name isn't listed, the phone number stays the same.

2 of 2
0

Based on Kusalananda's answer, if you only want to search and replace 2 values you can do somethig like this in one jq invocation:

jq '( .contacts[] | select(.name == "John") ).phone |= "4321" | 
    ( .contacts[] | select(.name == "Jane") ).phone |= "8765"' \
    contacts.json

Or this way chaining 2 jq invocations:

cat contacts.json | \
jq '( .contacts[] | select(.name == "John") ).phone |= "4321"' | \
jq '( .contacts[] | select(.name == "Jane") ).phone |= "8765"'
Find elsewhere
🌐
Gunnar Morling
morling.dev › blog › extracting-and-propagating-multiple-values-with-jq
Shell Spell: Extracting and Propagating Multiple Values With jq - Gunnar Morling
July 6, 2024 - The resulting JSON is piped to jq for extracting the values of password and host: jq is invaluable for handling JSON and I highly recommend spending some time with its reference documentation to learn about it. For the case at hand, the select() function is used within a pipeline for finding the right elements within the array of Terraform child modules and extracting the required values.
Top answer
1 of 2
4

You want to run a .context,.score filter on each element of v I think:

$ jq -r '.[] | [.c, .e, .score, (.v[] | .context,.score)] | @csv' file.json
"A","B",0.99,"asdf",0.98,"bcdfd",0.97

This is equivalent to using the builtin map function without assembling the results back into an array.

2 of 2
2

The following creates a JSON-encoded CSV record for each top-level array element, and then extracts and decodes them. For each of the top-level elements, the values of the sub-array is incorporated by "flattening" the array.

jq -r 'map([ .c,.e,.score, (.v|map([.context, .score])) ] | flatten | @csv)[]' file

Given a test document equivalent of the following:

[
   {
      "c": "A",
      "e": "B",
      "score": 0.99,
      "v": [
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "bcdfd", "score": 0.97, "url": "..." }
      ]
   },
   {
      "c": "A",
      "e": "B",
      "score": 0.99,
      "v": [
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "bcdfd", "score": 0.97, "url": "..." }
      ]
   },
   {
      "c": "A",
      "e": "B",
      "score": 0.99,
      "v": [
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "asdf", "score": 0.98, "url": "..." },
         { "context": "bcdfd", "score": 0.97, "url": "..." }
      ]
   }
]

... we get

"A","B",0.99,"asdf",0.98,"bcdfd",0.97
"A","B",0.99,"asdf",0.98,"asdf",0.98,"bcdfd",0.97
"A","B",0.99,"asdf",0.98,"asdf",0.98,"asdf",0.98,"bcdfd",0.97

One could also reorder the operations so that a single use of the @csv operator gets a set of arrays (rather than repeatedly using @csv on single arrays):

jq -r 'map([ .c,.e,.score, (.v|map([.context, .score])) ] | flatten)[]|@csv' file
🌐
Earthly
earthly.dev › blog › jq-select
JQ Select Explained: Selecting elements from JSON with Examples - Earthly Blog
July 24, 2023 - The only difference is you can use the object and array queries you’ve built up as the values. Returning to my GitHub API problem, to wrap the number and the title up into an array I use the object constructor like this: $ curl https://api.github.com/repos/stedolan/jq/issues?per_page=2 | \ jq '[ .[] | { title: .title, number: .number} ]'
🌐
Reddit
reddit.com › r/commandline › jq: extract element from object or array of objects
r/commandline on Reddit: jq: Extract element from object or array of objects
May 10, 2025 -

Given the following JSON, what is the best way to extract the phone numbers, whether inside an object or an array of objects?

{
  "phones": {
    "Alex Baker": { "location": "mobile", "number": "+14157459038" },
    "Bob Clarke": [
      { "location": "mobile", "number": "+12135637813" },
      { "location": "office", "number": "+13104443200" }
    ],
    "Carl Davies": [
      { "location": "office", "number": "+14083078372" },
      { "location": "lab", "number": "+15102340052" }
    ],
    "Drew Easton": { "location": "office", "number": "+18057459038" }
  }
}

I'm using the following query, but I wonder if there's a better way to do this:

$ cat phones.json | jq '.phones | to_entries | [ .[].value | objects | .number ] + [ .[].value | arrays | .[].number ]'
[
  "+14157459038",
  "+18057459038",
  "+12135637813",
  "+13104443200",
  "+14083078372",
  "+15102340052"
]

Any suggestions will be appreciated, thanks!

🌐
GitHub
github.com › jqlang › jq › issues › 785
Is it possible to output multiple values on a single line? · Issue #785 · jqlang/jq
May 12, 2015 - jq '.object1,.object2,.object3' returns the value for these objects each on a new line: "value1" "value2" "value3" Is there an option, or some filter to output these values on a single line, sepera...
Published   May 12, 2015
Author   Reino17
🌐
Mark Needham
markhneedham.com › blog › 2021 › 05 › 19 › jq-select-multiple-keys
jq: Select multiple keys | Mark Needham
May 19, 2021 - [ [ "/api/aggregation/$valuation", "post", "GetValuation", "[BETA] Perform valuation for a list of portfolios and/or portfolio groups" ] ] [ [ "/api/allocations", "get", "ListAllocations", "[EXPERIMENTAL] List Allocations" ], [ "/api/allocations", "post", "UpsertAllocations", "[EXPERIMENTAL] Upsert Allocations" ] ] [ [ "/api/allocations/{scope}/{code}", "delete", "DeleteAllocation", "[EXPERIMENTAL] Delete allocation" ], [ "/api/allocations/{scope}/{code}", "get", "GetAllocation", "[EXPERIMENTAL] Get Allocation" ] ] And then to flatten it out into single arrays instead of nested ones, we can pi
🌐
GitHub
gist.github.com › olih › f7437fb6962fb3ee9fe95bda8d2c8fa4
jq Cheet Sheet · GitHub
# here getpath/1 will get ["log"] both as implicit input and as it's first "explicit" input (the path to get) $ jq '["log"] | getpath(.)' example.json jq: error (at example.json:27): Cannot index array with string "log" # by using "... as $something" you will "bind" the value ["log"] to $p, this also make the input passthru so that # getpath will get json from example.json as input and then $p as the path to get $ jq '["log"] as $p | getpath($p)' example.json "123abc" and in the comment above path(..) as $p will cause each output of path(..) to be bound to $p and the rest of the pipeline is evaluated each time ·
🌐
Bashoneliners
bashoneliners.com › oneliners › 332
Printing with jq multiple values in CSV or TSV formats | bashoneliners.com
October 13, 2023 - The jq command filters and transforms the JSON content: .[] for each object in the JSON array input, ... [.id, .name, .stargazers_count] create a JSON array from the object's fields ... @cvs convert a JSON array to a single string of comma separated values. The -r (or --raw-output) flag makes jq print the output as raw values, which makes string values printed without enclosing double-quotes.
🌐
Proinsias
proinsias.github.io › til › jq-getting-all-the-values-of-an-array
Jq: Getting all the values of an array - Looking for data in all the right places…
May 13, 2025 - You can extract the values of the text field from the array using jq: > jq '.response[].text?' file.json "blabla" "blabla2" "blabla3" Or you can select using the type of each array element using either jq '.response[] | objects | .text' file.json or jq '.response[] | select(type=="object" and has("text")) | .text' file.json ·