Say you have a file (e.g. numbers.txt
) with one number per line and you need to sum them all up.
1
2
3
First off, for such a simple task and such a small file you can always do:
# jq -s 'add' numbers.txt
6
In case you wonder: -s
causes the file to be loaded into an array which is then passed to add
. So essentially what's happening is [1,2,3] | add
.
However for the purpose of this post, we're going to use reduce
& friends:
# jq -n 'reduce inputs as $n (0; . + $n)' numbers.txt
6
The -n
option is quite important here and is something that has tripped me up way too many times that I care to admit.
But before I explain what -n
means, let's see what running the same command without it yields:
# jq 'reduce inputs as $n (0; . + $n)' numbers.txt
5
Obviously wrong and we can guess that the first input (i.e. the first line of the file) has gone AWOL. (Another thing I wasted way too much time on.)
The clue is in the doc for inputs
:
Outputs all remaining inputs, one by one.
So how do I get the first input? With .
of course:
# jq 'reduce inputs as $n (.; . + $n)' numbers.txt
6
So .
holds the first line of the file whilst inputs
holds the remaining ones.
However sometimes the initialisation sequence of a reducer is similar to the iteration sequence e.g.,
# jq 'reduce inputs as $n (. * 10; . + ($n * 10))' numbers.txt
60
Again, this is a simple and contrived example so it's probably ok to repeat yourself here but there's a way to have the entire file emitted by inputs
. That's where -n
comes in:
Don't read any input at all. Instead, the filter is run once using null as the input.
So -n
causes null
to be emitted as the first input, which means that 1
and all the remaining numbers are emitted by inputs
:
# jq -n 'reduce inputs as $n (0; . + ($n * 10))' numbers.txt
60
The -n
is often useful when you just want to try out some stuff quickly e.g.,
# jq -n '[1,2,3] | add'
6
Top comments (0)