In general, the elements of an array may be converted to a single space-delimited string using join(" ")
in jq
. In your case, the .source
array may be converted into a space-delimited string using .source | join(" ")
.
I'm assuming that your input document contains an array of objects of the type that you show in the question.
Instead of calling jq
multiple times in each iteration, consider using jq
to get the data into a form that is usable as a single stream:
jq -r '.[] | [ .name, (.source | join(" ")) ] | @tsv' file.json | while IFS=$'\t' read -r name source; do __test "$name" "$source" done
This provides two tab-delimited fields to the loop. The first field is simply the .name
value from the JSON document, while the second field is a space-delimited string made by concatenating the elements from the .source
array. The concatenation of array elements into a singe string is done with join()
in jq
, and the tab-delimited output is produced by providing @tsv
with an array.
If you feel brave, you could even use
eval "$( jq -r '.[] | [ "__test", .name, (.source | join(" ")) ] | @sh' file.json )"
This uses jq
to actually create the shell commands that you aim to execute. The calling shell then gets this script as a string and runs it with eval
. In the jq
expression, @sh
is used to provide proper quoting for the command name and its arguments. The jq
expression here expects an array of objects of the type shown in the question.
jq
has a built in function for joining elements of an arrayjq -r '.source | join(" ")'
and also a built in TSV filterjq -r '.source | @tsv'