One way of doing it would be to not trying to do it in jq
, and instead use jq
to output a shell statement to do it in the shell instead:
eval "$(
jq -r -n '
{ "title": "A sample name", "number": 1214 } |
[ "printf", "%s %10s\\n", .title, .number ] | @sh'
)"
or,
eval "$(
printf '%s\n' '{ "title": "A sample name", "number": 1214 }' |
jq -r '[ "printf", "%s %10d\\n", .title, .number ] | @sh'
)"
or,
printf '%s\n' '{ "title": "A sample name", "number": 1214 }' |
{
eval "$(
jq -r '[ "printf", "%s %10s\\n", .title, .number ] | @sh'
)"
}
The jq
command would output
'printf' '%s %10s\n' 'A sample name' 1214
using the @sh
operator to properly quote each bit of the command safely.
When evaluated, this would output
A sample name 1214
A similar approach, but giving you two variable assignments instead:
jq -r -n '
{ "title": "A sample name", "number": 1214 } |
@sh "title=\(.title)",
@sh "number=\(.number)"'
(not to be used with arbitrary JSON where title
/number
are not guaranteed to be scalar. If they could be arrays, that would constitute an arbitrary command execution vulnerability).
You would then use these variables in your script:
unset -v title number
eval "$(
jq -r -n '
{ "title": "A sample name", "number": 1214 } |
@sh "title=\(.title)",
@sh "number=\(.number)"'
)"
printf '%s %10s\n' "$title" "$number"
For cases where the data is known to be nice (the title can't contain newlines, for example), you could possibly do
jq -r -n '
{ "title": "A sample name", "number": 1214 } |
[ .title, .number ] | @sh' |
xargs printf '%s %10s\n'
That is, make sure that the data is quoted, and then pass it to printf
in the shell (this would call the external utility printf
, not a shell built-in).