I did find a solution while I was writing the question: don't put the input inside string interpolation, output a stream of things:
echo '{"foo":"bar", "baz":[1,2,3]}' | jq -r '"My value is:", . , "Some other stuff"'
# .........................................................^^^^^
outputs
My value is:
{
"foo": "bar",
"baz": [
1,
2,
3
]
}
Some other stuff
Answer from glenn jackman on Stack OverflowI did find a solution while I was writing the question: don't put the input inside string interpolation, output a stream of things:
echo '{"foo":"bar", "baz":[1,2,3]}' | jq -r '"My value is:", . , "Some other stuff"'
# .........................................................^^^^^
outputs
My value is:
{
"foo": "bar",
"baz": [
1,
2,
3
]
}
Some other stuff
This might not fit your actual use case, but instead of creating a single JSON string in jq, just use a shell command group.
echo '{"foo":"bar", "baz":[1,2,3]}' | { echo "My value is:"; jq .; echo "Some other stuff"; }
jq does not pretty print when output is not a terminal
json - How to pretty print using jq, so that multiple values are on the same line? - Stack Overflow
Support pretty-printing and colorizing JSON responses for the `api` command when using `jq` expressions
Pretty print your sway tree (bash script, jq is the only dependency)
Videos
While it is probably best to use a tool like the one peak suggested if your json isn't too complex you could use a second jq invocation to postprocess the output of the first. For example if your data is in data.json
$ jq -M . data.json | jq -MRsr 'gsub("\n +";"")|gsub("\n ]";"]")'
produces
{
"frameGrid": {
"size": [24,24],
"dimensions": [1,1],
"names": [["default"]]
}
}
As @jq170727 mentioned, postprocessing after a pretty-printing run of jq (e.g. jq .) is worth considering. In that vein, here is an awk script that might suffice:
#!/bin/bash
awk '
function ltrim(x) { sub(/^[ \t]*/, "", x); return x; }
s && NF > 1 && $NF == "[" { s=s $0; next}
s && NF == 1 && $1 == "]," { print s "],"; s=""; next}
s && NF == 1 && $1 == "[" { print s; s=$0; next}
s && NF == 1 && $1 == "{" { print s; print; s=""; next}
s && NF == 1 && $1 == "]" { print s $1; s=""; next}
s && NF == 1 && $1 == "}" { print s; s=$0; next}
s { s=s ltrim($0); next}
$NF == "[" { s=$0; next}
{print}
'
Examples
With the example input, the invocation:
jq . example.json | ./pp
produces:
{
"frameGrid": {
"size": [24,24],
"dimensions": [1,1],
"names": [
["default"]
]
}
}
The invocation:
jq -n '{a:[1,2,3,[1,2,3,4]],b:2,c:{d:[1,2,{e:[3,4]}]}}' | ./pp
produces:
{
"a": [1,2,3,
[1,2,3,4]
],
"b": 2,
"c": {
"d": [1,2,
{
"e": [3,4]
}
]
}
}