starchaser
starchaser

Reputation: 361

jq combine output on a single line separated by space

I am trying to run a jq query on a windows machine and it extracts values from output on a separate line

jq -r .Accounts[].Id

Output

204359864429
224271824096
282276286062
210394168456
090161402717

How do I run the jq query so that it combines the output on a single line separated by space

This is what I need-

204359864429 224271824096 282276286062 210394168456 090161402717

Any help would be appreciated.

Upvotes: 36

Views: 23643

Answers (4)

James Yang
James Yang

Reputation: 636

If you run jq in a shell, you can use xargs like below:

jq -r .Accounts[].Id | xargs

output:

204359864429 224271824096 282276286062 210394168456 090161402717

The best parts of this way is if you have more fields you can add more control:

jq -r '.Accounts[] | .Id, .Name' | xargs -n2

The output like below:

204359864429 A
224271824096 B
282276286062 C
210394168456 D
090161402717 E

Upvotes: 6

CODE-REaD
CODE-REaD

Reputation: 3028

At first I thought the join() solution above did not work. Then I realized that I was "overfeeding" the join() filter, causing it to fail because I was providing more than a simple array as input. I had concatenated several filters with , and failed to limit the scope of my join().

Did not work:

jq -r \
'.ansible_facts |
 .ansible_hostname,
 .ansible_all_ipv4_addresses | join(" "),
 .ansible_local."aws-public-ipv4".publicIP'

This gave the error,

jq: error (at <stdin>:0): Cannot iterate over string ("hostone")

because jq was attempting to "consume" not only ansible_all_ipv4_addresses but also the output of the preceding ansible_hostname filter (I am not certain why this is or whether it was even intended by the author of jq).

Does work:

jq -r \
'.ansible_facts |
 .ansible_hostname,
 (.ansible_all_ipv4_addresses | join(" ")),
 .ansible_local."aws-public-ipv4".publicIP'

Here, I restrict join() to .ansible_all_ipv4_addresses only (ansible_all_ipv4_addresses is an array of IP addresses I wish to translate into a single, space-separated string).


P.S.: I found that the @sh filter produces space-separated output as desired, but in addition delimits each output item in single quotes.


P.P.S.: Here was my workaround, until I discovered that join() works just the same as it when used properly (see above):

jq -r '.Accounts[].Id | @tsv | sub("\t";" ";"g")'

Explanation: the @tsv filter produces Tab Separated Values, then the sub() filter substitutes tabs with spaces, globally.

Upvotes: 3

Ryan
Ryan

Reputation: 2020

You can use the @sh formatter:

jq -r ".Accounts[].Id | @sh"

From the jq docs:

The input is escaped suitable for use in a command-line for a POSIX shell. If the input is an array, the output will be a series of space-separated strings.

Reference:

https://stedolan.github.io/jq/manual/#Basicfilters

Upvotes: 17

Inian
Inian

Reputation: 85560

The usual way would be to use the @csv or @tsv operators to convert the result in the CSV or tab-delimited format. These operators need the result to be contained in an array. For your case also to have a single space delimit, we can do a simple join(" ") operation

jq -r '[.Accounts[].Id]|join(" ")'

Upvotes: 30

Related Questions