learnin'
jq
Of course, the jq
manual is the source.
+
*
/
explode
implode
explode
inside($str)
contains($substr)
inside
the input stringstartswith(str)
, endswith(str)
ltrimstr(str)
, rtrimstr(str)
not recursive/repetitive
"hellooo" | rtrimstr("o")
# => "helloo"
split(str)
split("")
returns an array of the input’s charactersascii_downcase
, ascii_upcase
"\(some expression)"
test(regex)
, test(regex; flags)
match(regex)
, match(regex; flags)
"foobar" | match("(?<first>...)(?<second>...)")
# => {
# => "offset": 0,
# => "length": 6,
# => "string": "foobar",
# => "captures": [
# => {
# => "offset": 0,
# => "length": 3,
# => "string": "foo",
# => "name": "first"
# => },
# => {
# => "offset": 3,
# => "length": 3,
# => "string": "bar",
# => "name": "second"
# => }
# => ]
# => }
empty
scan(regex)
, scan(regex; flags)
capture(regex)
, capture(regex; flags)
returns an object mapping capture name to substring
"foobar" | capture("(?<first>...)(?<second>...)")
# => { "first": "foo", "second": "bar" }
sub(regex; string)
, sub(regex; string; flags)
gsub(regex; string)
, gsub(regex; string; flags)
.[]
.[idx]
idx
.[from;to]
from
(inclusive) up to index to
(exclusive)+
-
add
indices(subarray)
output an array of indices indicating where the subarray exists inside the input array
[1, 2, 3, 4, 2, 3, 5] | indices([2, 3])
# => [1, 4]
contains(elems)
elems
satisfies the string contains
on some element of the input array.this is not an element-equality comparison
["foobar"] | contains(["foo", "bar"])
# => true
inside(ary)
contains
length
map(filter)
sort
, sort_by(path_exp)
group_by(path_exp)
unique
, unique_by(path_exp)
min
, max
, min_by(path_exp)
, max_by(path_exp)
join(str)
transpose
bsearch(x)
contains
test though+
*
+
but descend recursively for common keys that have objects as
valueskeys
, keys_unsorted
del(key)
has(key)
in(obj)
has
map_values(filter)
runs the filter on each value
{a:1, b:2} | map_values(. + 10)
# => {a: 11, b: 12}
to_entries
convert a object to an array of {key, value}
objects
{a:1, b:2} | to_entries
# => [{ key: "a", value: 1}, {key: "b", value: 2}]
Works with arrays too: the keys are the numeric indexes
["foo", "bar", "baz"] | to_entries
# => [{"key":0,"value":"foo"},{"key":1,"value":"bar"},{"key":2,"value":"baz"}]
from_entries
is the inverse
from_entries
on array|to_entries
– keys aren’t strings.with_entries(foo)
is a shorthand for
to_entries | map(foo) | from_entries
empty
select(filter)
filter
outputs a true value, pass the input unchangedempty
filtering an array uses map and select
[1, 2, 3, 4] | map(select(. < 3))
# => [1, 2]
reduce exp as $item (initial; reducer)
exp
and each result is bound to $item
reducer
, .
is the accumulatorerror(msg)
, halt
, halt_error
, halt_error(exit_status)
error
can be caught with try exp1 catch exp2
halt
exits with status 0halt_error
is like error(.) | halt
but with the given exit_status
(default: 5)range(upto)
, range(from; upto)
, range(from; upto; by)
from
(default zero) is inclusiveupto
is exclusivetostring
$ENV
env
, outputs $ENV
@text
calls tostring
@json
to serialize@html
XML encoding@uri
percent encoding@csv
@tsv
@sh
@base64
, @base64d
See Dates
if A then B else C end
else
clause required in v1.6and
, or
, not
a // b
if a then a else b end
false
and null
are falseexp as $identifier | ...
exp
, run the rest of the pipeline with
the entire original input, and with $x
set to that value.. as {realnames: $names, posts: [$first, $second]} | ..
def identifier: exp;
def identifier(arg1; arg2; ...): exp;
def identifier($arg1): exp;
def identifier(arg): arg as $arg | exp;
This caused me confusion in this situation:
def code: ...;
def encipher($code);
(. | code) as $result
| ...;
("xyz" | code) as $key
| "foobar" | encipher($key)
I was baffled that $result
was always $key
instead of calling
the function code
.
Eventually the “arg as $arg” shortcut dawned on me:
code
was the argument filter passed in, overriding the function.
value | func
floor
, ceil
, round
, sqrt
, exp
, log
, cos
, etcfunc(arg1; arg2)
hypot
, pow
, etcinput
, inputs
input_filename
, input_line_number
debug
stderr
include RelativePathString;
import RelativePathString as Name;
include
s code inside the Name
namespaceName::funcname
import RelativePathString as $Name;
$Name::Name
bindingany
and all
while(cond; update)
, until(cond; update)
foreach exp as $var (init; update; extract)
break $label
limit(n; exp)
and nth(n; exp)
and generators
example from manual:
echo 1 | jq '
# re-implement builtin `while`
def while(cond; update):
def _while:
if cond
then ., (update | _while)
else empty
end;
_while;
# generate an infinite stream of doubling numbers,
# but take the 5th result and quit
nth(5; while(true; .*2))
'
32
histgram
$ jq -n '"hello" / "" | group_by(.) | map({key: .[0], value: length}) | from_entries'
{
"e": 1,
"h": 1,
"l": 2,
"o": 1
}
two arrays have the same elements:
[1,2,3] == [3,2,1]
# => false
,
([1,2,3] | inside([3,2,1])) and ([1,2,3] | contains([3,2,1]))
# => true
Better expressed using IN
and all
[1, 2, 3] | all(IN([3, 2, 1] | .[]))
# => true
The IN
argument is a stream