I'm frequently passed long shell one-liners that require some visual inspection before running. These days, there's about as much jq in that one-liner as there is bash. I wrote jqfmt to help add line breaks in sensible locations while reading (or writing!) jq.
At time of initial development, I naturally turned to https://github.com/itchyny/gojq expecting to be able to generate and walk a syntax tree—but gojq didn't seem to provide an AST that could be "walked," and it doesn't export its parsing logic to be used in library form. So, I yanked the relevant code out of https://github.com/itchyny/gojq/blob/main/query.go and started from there.
Side note: Ever tried Googling for "jq formatter"? Reading search results is a nightmare since jq itself is, among other things, a formatter.
go install -v github.com/noperator/jqfmt/cmd/jqfmt@latest
𝄢 jqfmt -h
Usage of jqfmt:
-ar
arrays
-f string
file
-o one line
-ob
objects
-op string
operators
-v verbose
Let's take this line of jq…
𝄢 echo '{one: .two, three: [.four, .five, [.fivetwo, .fivethree]], six: map(select((.seven | .eight | .nine)))}' |
jqfmt
{ one: .two, three: [.four, .five, [.fivetwo, .fivethree]], six: map(select((.seven | .eight | .nine))) }
…and format objects.
𝄢 echo '{one: .two, three: [.four, .five, [.fivetwo, .fivethree]], six: map(select((.seven | .eight | .nine)))}' |
jqfmt -ob
{
one: .two,
three: [.four, .five, [.fivetwo, .fivethree]],
six: map(select((.seven | .eight | .nine)))
}
Nice! Let's also do arrays.
𝄢 echo '{one: .two, three: [.four, .five, [.fivetwo, .fivethree]], six: map(select((.seven | .eight | .nine)))}' |
jqfmt -ob -ar
{
one: .two,
three: [
.four,
.five,
[
.fivetwo,
.fivethree
]
],
six: map(select((.seven | .eight | .nine)))
}
It'll read easier if we also break on pipes.
𝄢 echo '{one: .two, three: [.four, .five, [.fivetwo, .fivethree]], six: map(select((.seven | .eight | .nine)))}' |
jqfmt -ob -ar -op pipe
{
one: .two,
three: [
.four,
.five,
[
.fivetwo,
.fivethree
]
],
six: map(select((.seven |
.eight |
.nine)))
}
Full list of valid operators
pipe
comma
add
sub
mul
div
mod
eq
ne
gt
lt
ge
le
and
or
alt
assign
modify
updateAdd
updateSub
updateMul
updateDiv
updateMod
updateAlt
- @zjzeit for helping me believe that formatting jq is a reasonable thing to do.
- @colindean for helping me believe that jqfmt was a reasonable thing to build.
- @tracertea for writing jq lines long enough to warrant a formatter.
- @addyosmani for "First do it, then do it right, then do it better." I wrote this on a plane (as the best tools are) over a year ago, but always had more features I wanted to add before releasing it. Doing it "right" might mean a refactor or clean-up; "better" would probably mean incorporating an AST.
- handle func definitions
- quickly format jq by appending
fmt
tojq
on the CLI
This project is licensed under the MIT License.