diff --git a/jq.1.prebuilt b/jq.1.prebuilt index e69de29bb2..7575f67746 100644 --- a/jq.1.prebuilt +++ b/jq.1.prebuilt @@ -0,0 +1,5323 @@ +.\" Automatically generated by Pandoc 3.4 +.\" +.TH "JQ" "1" "" "" +.SH NAME +jq \[en] Command\-line JSON processor +.SH SYNOPSIS +\f[B]jq\f[R] \f[CR][\f[R]\f[I]OPTION\f[R]\f[CR]]\f[R]\&... +\f[CR][\f[R]\f[I]FILTER\f[R]\f[CR]]\f[R] +\f[CR][\f[R]\f[I]FILE\f[R]\f[CR]]\f[R]\&... +.SH DESCRIPTION +jq is a tool to transform JSON data in various ways, such as selecting, +iterating, and reducing. +For instance, running the command +\f[CR]jq \[aq]map(.price) | add\[aq]\f[R] takes an array of JSON objects +as input and returns the sum of their \[lq]price\[rq] fields. +.PP +A jq program, such as \f[CR]map(.price) | add\f[R], is called a +\f[I]filter\f[R]. +Each filter takes an input value and produces a \f[I]stream\f[R] of +output values. +For instance, when the input value is an array, the filter +\f[CR].[]\f[R] yields all the elements of the array. +Even literals like \f[CR]\[dq]hello\[dq]\f[R] or \f[CR]42\f[R] are +filters \[em] they take an input, ignore it, and produce the same +literal as output. +.PP +The simplest filter (or jq program) is identity \f[CR].\f[R], which +simply outputs its input. +Because the default behavior of jq is to pretty\-print all outputs, you +can use \f[CR]jq \[aq].\[aq]\f[R] to validate and pretty\-print JSON +input. +However, the jq programming language is quite rich and allows for much +more than just validation and pretty\-printing. +.PP +There are many filters for various standard tasks, such as extracting a +particular field of an object, or converting a number to a string. +.PP +Filters can be combined in various ways. +For example, you can feed the output of one filter to another filter, or +collect the output of a filter into an array. +Generally, things that would be done with loops and iteration in other +languages are just done by gluing filters together in jq. +.PP +We can run a filter \f[CR]FILTER\f[R] using \f[CR]jq FILTER\f[R], +e.g.\ \f[CR]jq .foo\f[R]. +For large filters, it may be more convenient to write it into some +\f[CR]FILE\f[R] and to run it using \f[CR]jq \-f FILE\f[R], +e.g.\ \f[CR]jq \-f filter.jq\f[R]. +.TP +\f[I]Note\f[R] +When using \f[CR]jq FILTER\f[R], it is important to mind the shell\[cq]s +quoting rules. +As a general rule, it\[cq]s best to always quote the jq program, because +many characters with special meaning to jq are also shell +meta\-characters. +For example, \f[CR]jq \[dq]foo\[dq]\f[R] will fail on most Unix shells +because that will be the same as \f[CR]jq foo\f[R], which will generally +fail because \f[CR]foo is not defined\f[R]. +The quoting rules depend on your shell: When using a Unix shell, use +single quotes around your jq program, When using the Windows command +shell (\f[CR]cmd.exe\f[R]), use \f[I]double quotes\f[R] around your jq +program and escape double quotes in the jq program with backslashes. +When using the Powershell (\f[CR]powershell.exe\f[R]) or the Powershell +Core (\f[CR]pwsh\f[R]/\f[CR]pwsh.exe\f[R]), use \f[I]single quotes\f[R] +around your jq program and escape double\-quotes in the jq program with +backslashes (\f[CR]\[rs]\[dq]\f[R]). +.IP \[bu] 2 +Unix shells: \f[CR]jq \[aq].[\[dq]foo\[dq]]\[aq]\f[R] +.IP \[bu] 2 +Powershell: \f[CR]jq \[aq].[\[rs]\[dq]foo\[rs]\[dq]]\[aq]\f[R] +.IP \[bu] 2 +Windows command shell: +\f[CR]jq \[dq].[\[rs]\[dq]foo\[rs]\[dq]]\[dq]\f[R] +.PP +By default, jq reads a stream of JSON values (including numbers and +other literals) from a list of files (or \f[CR]stdin\f[R] if no files +are given), Whitespace is only needed to separate numbers (such as 1 and +2) and booleans (true and false). +Using \f[CR]\-\-raw\-input\f[R], jq accepts arbitrary text as input. +jq runs the given filter on each input value, and writes all output +values of the filter to standard output, as a sequence of +newline\-separated JSON values. +.SH COMMAND\-LINE OPTIONS +.TP +\f[I]Compatibility\f[R] +There exist several compilers/interpreters for the jq language; the +reference implementation is called jq, but there is also \c +.UR https://github.com/itchyny/gojq/ +gojq +.UE \c +\ and \c +.UR https://github.com/01mf02/jaq +jaq +.UE \c +\&. +This manual tries to point out when these implementations diverge from +the reference implementation. +.PP +You can affect how jq reads and writes its input and output using some +command\-line options: +.SS General options +.IP \[bu] 2 +\f[CR]\-f\f[R] / \f[CR]\-\-from\-file\f[R]: +.RS 2 +.PP +Read filter from a file rather than from the command line, like +awk\[cq]s \f[CR]\-f\f[R] option. +This changes the filter argument to be interpreted as a filename, +instead of the source of a program. +.RE +.IP \[bu] 2 +\f[CR]\-L directory\f[R] / \f[CR]\-\-library\-path directory\f[R]: +.RS 2 +.PP +Prepend \f[CR]directory\f[R] to the search paths for modules. +If this option is used then no builtin search paths are used. +.RE +.IP \[bu] 2 +\f[CR]\-\-exit\-status\f[R] / \f[CR]\-e\f[R]: +.RS 2 +.PP +Sets the exit status of jq to 0 if the last output value was neither +\f[CR]false\f[R] nor \f[CR]null\f[R], 1 if the last output value was +either \f[CR]false\f[R] or \f[CR]null\f[R], or 4 if no valid result was +ever produced. +Normally jq exits with 2 if there was any usage problem or system error, +3 if there was a jq program compile error, or 0 if the jq program ran. +.PP +You can also set the exit status with the \f[CR]halt_error\f[R] +function. +.RE +.IP \[bu] 2 +\f[CR]\-\-version\f[R] / \f[CR]\-V\f[R]: +.RS 2 +.PP +Output the jq version and exit with zero. +.RE +.IP \[bu] 2 +\f[CR]\-\-help\f[R] / \f[CR]\-h\f[R]: +.RS 2 +.PP +Output the jq help and exit with zero. +.RE +.IP \[bu] 2 +\f[CR]\-\-\f[R]: +.RS 2 +.PP +Terminates argument processing. +Remaining arguments are not interpreted as options. +.RE +.SS Input options +.IP \[bu] 2 +\f[CR]\-\-null\-input\f[R] / \f[CR]\-n\f[R]: +.RS 2 +.PP +Don\[cq]t read any input at all. +Instead, the filter is run once using \f[CR]null\f[R] as the input. +This is useful when using jq as a simple calculator, to construct JSON +data from scratch, or in conjunction with the \f[CR]input\f[R] / +\f[CR]inputs\f[R] filters. +.RE +.IP \[bu] 2 +\f[CR]\-\-raw\-input\f[R] / \f[CR]\-R\f[R]: +.RS 2 +.PP +Don\[cq]t parse the input as JSON. +Instead, each line of text is passed to the filter as a string. +If combined with \f[CR]\-\-slurp\f[R], then the entire input is passed +to the filter as a single long string. +.RE +.IP \[bu] 2 +\f[CR]\-\-slurp\f[R] / \f[CR]\-s\f[R]: +.RS 2 +.PP +Instead of running the filter for each JSON object in the input, read +the entire input stream into a large array and run the filter just once. +.TP +\f[I]Compatibility\f[R] +When this option is used, jq combines the inputs of all files into one +single array, whereas jaq yields an array for every file. +This is motivated by jaq\[cq]s \f[CR]\-i\f[R] / \f[CR]\-\-in\-place\f[R] +option, which could not work with the slurping behaviour implemented by +jq. +The behaviour of jq can be approximated in jaq; for example, to achieve +the output of \f[CR]jq \-s . a b\f[R], you may use +\f[CR]jaq \-s . <(cat a b)\f[R]. +.RE +.IP \[bu] 2 +\f[CR]\-\-stream\f[R]: +.RS 2 +.PP +Parse the input in streaming fashion, outputting arrays of path and leaf +values (scalars and empty arrays or empty objects). +For example, \f[CR]\[dq]a\[dq]\f[R] becomes \f[CR][[],\[dq]a\[dq]]\f[R], +and \f[CR][[],\[dq]a\[dq],[\[dq]b\[dq]]]\f[R] becomes +\f[CR][[0],[]]\f[R], \f[CR][[1],\[dq]a\[dq]]\f[R], and +\f[CR][[2,0],\[dq]b\[dq]]\f[R]. +.PP +This is useful for processing large inputs incrementally, in particular +in conjunction with filtering and the \f[CR]reduce\f[R] and +\f[CR]foreach\f[R] filters. +.PP +Several builtin functions help processing streaming input. +.TP +\f[I]Compatibility\f[R] +jaq does not support this option. +.RE +.IP \[bu] 2 +\f[CR]\-\-stream\-errors\f[R]: +.RS 2 +.PP +Like \f[CR]\-\-stream\f[R], but invalid JSON inputs yield array values +where the first element is the error and the second is a path. +For example, \f[CR][\[dq]a\[dq],n]\f[R] produces +\f[CR][\[dq]Invalid literal at line 1, column 7\[dq],[1]]\f[R]. +.PP +Implies \f[CR]\-\-stream\f[R]. +Invalid JSON inputs produce no error values when \f[CR]\-\-stream\f[R] +without \f[CR]\-\-stream\-errors\f[R]. +.TP +\f[I]Compatibility\f[R] +jaq does not support this option. +.RE +.SS Output options +.IP \[bu] 2 +\f[CR]\-\-compact\-output\f[R] / \f[CR]\-c\f[R]: +.RS 2 +.PP +By default, jq pretty\-prints JSON output. +Using this option will result in more compact output by instead +outputting each JSON object on a single line. +.RE +.IP \[bu] 2 +\f[CR]\-\-raw\-output\f[R] / \f[CR]\-r\f[R]: +.RS 2 +.PP +With this option, if the filter\[cq]s result is a string then it will be +written directly to standard output rather than being formatted as a +JSON string with quotes. +This can be useful for making jq filters talk to non\-JSON\-based +systems. +.RE +.IP \[bu] 2 +\f[CR]\-\-raw\-output0\f[R]: +.RS 2 +.PP +Like \f[CR]\-r\f[R] but jq will print NUL instead of newline after each +output. +This can be useful when the values being output can contain newlines. +When an output value contains NUL, jq exits with non\-zero code. +.TP +\f[I]Compatibility\f[R] +jaq does not support this option. +.RE +.IP \[bu] 2 +\f[CR]\-\-join\-output\f[R] / \f[CR]\-j\f[R]: +.RS 2 +.PP +Like \f[CR]\-r\f[R] but jq won\[cq]t print a newline after each output. +.TP +\f[I]Compatibility\f[R] +In jaq, this does not enable \f[CR]\-\-raw\-output\f[R]. +.RE +.IP \[bu] 2 +\f[CR]\-\-ascii\-output\f[R] / \f[CR]\-a\f[R]: +.RS 2 +.PP +jq usually outputs non\-ASCII Unicode codepoints as UTF\-8, even if the +input specified them as escape sequences (like \[lq]3bc\[rq]). +Using this option, you can force jq to produce pure ASCII output with +every non\-ASCII character replaced with the equivalent escape sequence. +.TP +\f[I]Compatibility\f[R] +gojq and jaq do not support this option. +.RE +.IP \[bu] 2 +\f[CR]\-\-sort\-keys\f[R] / \f[CR]\-S\f[R]: +.RS 2 +.PP +Output the fields of each object with the keys in sorted order. +.TP +\f[I]Compatibility\f[R] +gojq always sorts the fields of objects by their keys, so it does not +support this option. +jaq does not support this option. +However, you can sort all output objects by their keys using a filter +such as: +.IP +.EX +walk(if . >= {} then reduce (keys[] as $k | { ($k): .[$k] }) as $o ({}; . + $o) end) +.EE +.RE +.IP \[bu] 2 +\f[CR]\-\-color\-output\f[R] / \f[CR]\-C\f[R] and +\f[CR]\-\-monochrome\-output\f[R] / \f[CR]\-M\f[R]: +.RS 2 +.PP +By default, jq outputs colored JSON if writing to a terminal. +You can force it to produce color even if writing to a pipe or a file +using \f[CR]\-C\f[R], and disable color with \f[CR]\-M\f[R]. +When the \f[CR]NO_COLOR\f[R] environment variable is not empty, jq +disables colored output by default, but you can enable it by +\f[CR]\-C\f[R]. +.PP +Colors can be configured with the \f[CR]JQ_COLORS\f[R] environment +variable. +.TP +\f[I]Compatibility\f[R] +In jaq, the corresponding options are called \f[CR]\-\-color=always\f[R] +and \f[CR]\-\-color=never\f[R]. +.RE +.IP \[bu] 2 +\f[CR]\-\-tab\f[R]: +.RS 2 +.PP +Use a tab for each indentation level instead of two spaces. +.RE +.IP \[bu] 2 +\f[CR]\-\-indent n\f[R]: +.RS 2 +.PP +Use the given number of spaces (no more than 7) for indentation. +.RE +.IP \[bu] 2 +\f[CR]\-\-unbuffered\f[R]: +.RS 2 +.PP +Flush the output after each JSON object is printed. +This is useful if you pipe a slow data source into jq and pipe jq\[cq]s +output elsewhere. +.TP +\f[I]Compatibility\f[R] +gojq and jaq do not support this option. +.RE +.IP \[bu] 2 +\f[CR]\-\-seq\f[R]: +.RS 2 +.PP +Use the \f[CR]application/json\-seq\f[R] MIME type scheme for separating +JSON texts in jq\[cq]s input and output. +This means that an ASCII RS (record separator) character is printed +before each value on output and an ASCII LF (line feed) is printed after +every output. +Input JSON texts that fail to parse are ignored (but warned about), +discarding all subsequent input until the next RS. +This mode also parses the output of jq without the \f[CR]\-\-seq\f[R] +option. +.TP +\f[I]Compatibility\f[R] +gojq and jaq do not support this option. +.RE +.IP \[bu] 2 +\f[CR]\-\-binary\f[R] / \f[CR]\-b\f[R]: +.RS 2 +.PP +Windows users using WSL, MSYS2, or Cygwin, should use this option when +using a native jq.exe, otherwise jq will turn newlines (LFs) into +carriage\-return\-then\-newline (CRLF). +.TP +\f[I]Compatibility\f[R] +gojq and jaq do not support this option. +.RE +.SS Variable options +.IP \[bu] 2 +\f[CR]\-\-arg name value\f[R]: +.RS 2 +.PP +This option passes a value to the jq program as a predefined variable. +If you run jq with \f[CR]\-\-arg foo bar\f[R], then \f[CR]$foo\f[R] is +available in the program and has the value \f[CR]\[dq]bar\[dq]\f[R]. +Note that \f[CR]value\f[R] will be treated as a string, so +\f[CR]\-\-arg foo 123\f[R] will bind \f[CR]$foo\f[R] to +\f[CR]\[dq]123\[dq]\f[R]. +.PP +Named arguments are also available to the jq program as +\f[CR]$ARGS.named\f[R]. +When the name is not a valid identifier, this is the only way to access +it. +.RE +.IP \[bu] 2 +\f[CR]\-\-argjson name JSON\-text\f[R]: +.RS 2 +.PP +This option passes a JSON\-encoded value to the jq program as a +predefined variable. +If you run jq with \f[CR]\-\-argjson foo 123\f[R], then \f[CR]$foo\f[R] +is available in the program and has the value \f[CR]123\f[R]. +.RE +.IP \[bu] 2 +\f[CR]\-\-slurpfile variable\-name filename\f[R]: +.RS 2 +.PP +This option reads all the JSON texts in the named file and binds an +array of the parsed JSON values to the given global variable. +If you run jq with \f[CR]\-\-slurpfile foo bar\f[R], then +\f[CR]$foo\f[R] is available in the program and has an array whose +elements correspond to the texts in the file named \f[CR]bar\f[R]. +.RE +.IP \[bu] 2 +\f[CR]\-\-rawfile variable\-name filename\f[R]: +.RS 2 +.PP +This option reads in the named file and binds its contents to the given +global variable. +If you run jq with \f[CR]\-\-rawfile foo bar\f[R], then \f[CR]$foo\f[R] +is available in the program and has a string whose contents are to the +texts in the file named \f[CR]bar\f[R]. +.RE +.IP \[bu] 2 +\f[CR]\-\-args\f[R]: +.RS 2 +.PP +Remaining arguments are positional string arguments. +These are available to the jq program as \f[CR]$ARGS.positional[]\f[R]. +.TP +\f[I]Compatibility\f[R] +jaq does not support this option. +.RE +.IP \[bu] 2 +\f[CR]\-\-jsonargs\f[R]: +.RS 2 +.PP +Remaining arguments are positional JSON text arguments. +These are available to the jq program as \f[CR]$ARGS.positional[]\f[R]. +.TP +\f[I]Compatibility\f[R] +jaq does not support this option. +.RE +.SS Development options +.IP \[bu] 2 +\f[CR]\-\-build\-configuration\f[R]: +.RS 2 +.PP +Output the build configuration of jq and exit with zero. +This output has no supported format or structure and may change without +notice in future releases. +.TP +\f[I]Compatibility\f[R] +gojq and jaq do not support this option. +.RE +.IP \[bu] 2 +\f[CR]\-\-run\-tests [filename]\f[R]: +.RS 2 +.PP +Runs the tests in the given file or standard input. +This must be the last option given and does not honor all preceding +options. +The input consists of comment lines, empty lines, and program lines +followed by one input line, as many lines of output as are expected (one +per output), and a terminating empty line. +Compilation failure tests start with a line containing only +\f[CR]%%FAIL\f[R], then a line containing the program to compile, then a +line containing an error message to compare to the actual. +.PP +This option can change backwards\-incompatibly. +.RE +.SS Colors +To configure alternative colors, you may set the \f[CR]JQ_COLORS\f[R] +environment variable to colon\-delimited list of partial terminal escape +sequences like \f[CR]\[dq]1;31\[dq]\f[R], in this order: +.IP \[bu] 2 +color for \f[CR]null\f[R] +.IP \[bu] 2 +color for \f[CR]false\f[R] +.IP \[bu] 2 +color for \f[CR]true\f[R] +.IP \[bu] 2 +color for numbers +.IP \[bu] 2 +color for strings +.IP \[bu] 2 +color for arrays +.IP \[bu] 2 +color for objects +.IP \[bu] 2 +color for object keys +.PP +The default color scheme is the same as setting +\f[CR]JQ_COLORS=\[dq]0;90:0;39:0;39:0;39:0;32:1;39:1;39:1;34\[dq]\f[R]. +.PP +This is not a manual for VT100/ANSI escapes. +However, each of these color specifications should consist of two +numbers separated by a semi\-colon. +The first number is one of these: +.IP \[bu] 2 +1 (bright) +.IP \[bu] 2 +2 (dim) +.IP \[bu] 2 +4 (underscore) +.IP \[bu] 2 +5 (blink) +.IP \[bu] 2 +7 (reverse) +.IP \[bu] 2 +8 (hidden) +.PP +The second number is one of these: +.IP \[bu] 2 +30 (black) +.IP \[bu] 2 +31 (red) +.IP \[bu] 2 +32 (green) +.IP \[bu] 2 +33 (yellow) +.IP \[bu] 2 +34 (blue) +.IP \[bu] 2 +35 (magenta) +.IP \[bu] 2 +36 (cyan) +.IP \[bu] 2 +37 (white) +.TP +\f[I]Compatibility\f[R] +jaq does not consider \f[CR]JQ_COLORS\f[R]. +.SH TYPES AND VALUES +jq supports the same set of data types as JSON \[em] booleans, numbers, +strings, arrays, objects (JSON\-speak for hashes with only string keys), +and \f[CR]null\f[R]. +This section covers how to create values in jq. +.PP +\f[CR]null\f[R], booleans, numbers, and strings are written the same way +as in JSON. +Just like everything else in jq, these simple values take an input and +produce an output. +For example, \f[CR]42\f[R] is a valid jq expression that takes an input, +ignores it, and returns 42. +.SS Booleans +The booleans can be produced by the filters \f[CR]true\f[R] and +\f[CR]false\f[R]. +.SS Numbers +Numbers in jq are internally represented by their IEEE754 double +precision approximation. +Any arithmetic operation with numbers, whether they are literals or +results of previous filters, will produce a double precision floating +point result. +.PP +However, when parsing a literal, jq stores the original literal string. +When a number which originally was provided as a literal is never +mutated until the end of the program, then its original literal form is +preserved. +This also includes cases when the original literal would be truncated +when converted to an IEEE754 double precision floating point number. +.TP +\f[I]Note\f[R] +Using the current implementation of jq, the expression +\f[CR]1E1234567890\f[R] produces \f[CR]1.7976931348623157e+308\f[R] on +at least one platform. +This is because, in the process of parsing the number, jq has converted +it to an IEEE754 double\-precision representation, losing precision. +The way in which jq handles numbers has changed over time. +Further changes are likely within the parameters set by the relevant +JSON standards. +Moreover, build configuration options can alter how jq processes +numbers. +The following remarks are therefore offered with the understanding that +they are intended to be descriptive of the current version of jq and +should not be interpreted as being prescriptive: +.IP "(1)" 4 +Any arithmetic operation on a number that has not already been converted +to an IEEE754 double precision representation will trigger a conversion +to the IEEE754 representation. +.IP "(2)" 4 +jq will attempt to maintain the original decimal precision of number +literals (unless the \f[CR]\-\-disable\-decnum\f[R] build configuration +option was used), but in expressions such as \f[CR]1E1234567890\f[R], +precision will be lost if the exponent is too large. +.IP "(3)" 4 +In jq programs, a leading minus sign triggers the conversion of the +number to an IEEE754 representation. +.IP "(4)" 4 +Comparisons are carried out using the untruncated big decimal +representation of numbers if available, as illustrated in one of the +following examples. +See the builtin function \f[CR]have_decnum\f[R] for examples where the +\f[CR]\-\-disable\-decnum\f[R] build configuration option matters. +.TP +\f[I]Compatibility\f[R] +In gojq and jaq, numbers are either floating\-point numbers or integers. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]. < 0.12345678901234567890123456788\[aq] \[rs] + <<< \[aq]0.12345678901234567890123456789\[aq] +false +.EE +.SS Strings +.SS String interpolation: \f[CR]\[rs](f)\f[R] +Inside a string, you can put a filter inside parentheses after a +backslash, such as: +.IP +.EX +\[dq]Hello \[rs](.name) of planet \[rs](.planet)!\[dq] +.EE +.PP +The output of the filter will be interpolated into the string. +The example above is equivalent to: +.IP +.EX +\[dq]Hello \[dq] + (.name | tostring) + \[dq] of planet \[dq] + (.planet | tostring) + \[dq]!\[dq] +.EE +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]\[dq]The input was \[rs](.), which is one less than \[rs](.+1)\[dq]\[aq] \[rs] + <<< \[aq]42\[aq] +\[dq]The input was 42, which is one less than 43\[dq] +.EE +.SS String formatting: \f[CR]\[at]f\f[R] +The \f[CR]\[at]foo\f[R] syntax is used to format and escape strings, +which is useful for building URLs, documents in a language like HTML or +XML, and so forth. +\f[CR]\[at]foo\f[R] can also be used as a filter on its own. +See below for a list. +.PP +This syntax can be combined with string interpolation in a useful way. +You can follow a \f[CR]\[at]foo\f[R] token with a string literal. +The contents of the string literal will \f[I]not\f[R] be escaped. +However, all interpolations made inside that string literal will be +escaped. +For instance, +.IP +.EX +\[at]uri \[dq]https://www.google.com/search?q=\[rs](.search)\[dq] +.EE +.PP +will produce the following output for the input +\f[CR]{\[dq]search\[dq]:\[dq]what is jq?\[dq]}\f[R]: +.IP +.EX +\[dq]https://www.google.com/search?q=what%20is%20jq%3F\[dq] +.EE +.PP +Note that the slashes, question mark, etc. +in the URL are not escaped, as they were part of the string literal. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]\[at]html\[aq] \[rs] + <<< \[aq]\[dq]This works if x < y\[dq]\[aq] +\[dq]This works if x < y\[dq] +.EE +.IP +.EX +$ jq \[aq]\[at]sh \[dq]echo \[rs](.)\[dq]\[aq] \[rs] + <<< \[aq]\[dq]O\[aq]Hara\[aq]s Ale\[dq]\[aq] +\[dq]echo \[aq]O\[aq]\[rs]\[rs]\[aq]\[aq]Hara\[aq]\[rs]\[rs]\[aq]\[aq]s Ale\[aq]\[dq] +.EE +.IP +.EX +$ jq \[aq]\[at]base64\[aq] \[rs] + <<< \[aq]\[dq]This is a message\[dq]\[aq] +\[dq]VGhpcyBpcyBhIG1lc3NhZ2U=\[dq] +.EE +.IP +.EX +$ jq \[aq]\[at]base64d\[aq] \[rs] + <<< \[aq]\[dq]VGhpcyBpcyBhIG1lc3NhZ2U=\[dq]\[aq] +\[dq]This is a message\[dq] +.EE +.SS Arrays: \f[CR][]\f[R], \f[CR][...]\f[R] +As in JSON, \f[CR][...]\f[R] is used to construct arrays, as in +\f[CR][1,2,3]\f[R]. +The elements of the arrays can be any jq expression. +All of the results produced by all of the expressions are collected into +one big array. +You can use it to construct an array out of a known quantity of values +(as in \f[CR][.foo, .bar, .baz]\f[R]) or to \[lq]collect\[rq] all the +results of a filter into an array (as in \f[CR][.items[].name]\f[R]) +.PP +Once you understand the concatenation operator (\f[CR],\f[R]), you can +look at jq\[cq]s array syntax in a different light: the expression +\f[CR][1,2,3]\f[R] is not using a built\-in syntax for comma\-separated +arrays, but is instead applying the \f[CR][]\f[R] operator (collect +results) to the expression \f[CR]1,2,3\f[R] (which produces three +different results). +.PP +If you have a filter \f[CR]f\f[R] that produces four results, then the +expression \f[CR][f]\f[R] will produce a single result, an array of four +elements. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][.user, .projects[]]\[aq] \[rs] + <<< \[aq]{\[dq]user\[dq]:\[dq]stedolan\[dq], \[dq]projects\[dq]: [\[dq]jq\[dq], \[dq]wikiflow\[dq]]}\[aq] +[\[dq]stedolan\[dq], \[dq]jq\[dq], \[dq]wikiflow\[dq]] +.EE +.IP +.EX +$ jq \[aq][.[] | . * 2]\[aq] \[rs] + <<< \[aq][1, 2, 3]\[aq] +[2, 4, 6] +.EE +.SS Objects: \f[CR]{}\f[R], \f[CR]{...}\f[R] +Like in JSON, \f[CR]{...}\f[R] is for constructing objects (aka +dictionaries or hashes), as in +\f[CR]{\[dq]a\[dq]: 42, \[dq]b\[dq]: 17}\f[R]. +Here, \f[CR]\[dq]a\[dq]\f[R] and \f[CR]\[dq]b\[dq]\f[R] are the +\f[I]keys\f[R] (or \f[I]fields\f[R]) of the object, and \f[CR]42\f[R] +and \f[CR]17\f[R] are the corresponding \f[I]values\f[R] of the object. +.PP +As keys, you can use constant literals, variables, or parenthesized +expressions, such as \f[CR]{(\[dq]a\[dq]+\[dq]b\[dq]):59}\f[R]. +As values, you can use any expression; however, an expression containing +colons needs to be surrounded by parentheses. +.PP +We say that a key is \f[I]identifier\-like\f[R] when it does not start +with a digit and consists only of alphanumeric characters and +underscores; for example, \f[CR]foo\f[R] is identifier\-like. +If a key is an identifier\-like string, such as +\f[CR]\[dq]foo\[dq]\f[R], then the quotes can be omitted. +For example, you may write \f[CR]{\[dq]a\[dq]:42, \[dq]b\[dq]:17}\f[R] +more succinctly as \f[CR]{a:42, b:17}\f[R]. +.PP +Key and value expressions are evaluated with the input of the +\f[CR]{...}\f[R] literal. +If one of the expressions produces multiple results, multiple objects +are produced. +.TP +\f[I]Example\f[R] +The filter +.IP +.EX +{user: \[dq]stedolan\[dq], title: (\[dq]JQ Primer\[dq], \[dq]More JQ\[dq])} +.EE +produces two outputs: +.IP +.EX +{\[dq]user\[dq]:\[dq]stedolan\[dq], \[dq]title\[dq]: \[dq]JQ Primer\[dq]} +{\[dq]user\[dq]:\[dq]stedolan\[dq], \[dq]title\[dq]: \[dq]More JQ\[dq]} +.EE +.TP +\f[I]Example\f[R] +The filter \f[CR]{(\[dq]a\[dq], \[dq]b\[dq]): 1}\f[R] outputs +\f[CR]{\[dq]a\[dq]: 1}\f[R] and \f[CR]{\[dq]b\[dq]: 1}\f[R]. +.PP +If an input object contains an entry \f[CR]\[dq]k\[dq]: v\f[R] where +\f[CR]k\f[R] is an identifier\-like key, then we can create a new object +\f[CR]{\[dq]k\[dq]: v}\f[R] by writing \f[CR]{k}\f[R]. +You can use this to select particular fields of an object. +.TP +\f[I]Example\f[R] +If the input is an object with \[lq]user\[rq], \[lq]title\[rq], +\[lq]id\[rq], and \[lq]content\[rq] fields, then you can obtain an +object with just the \[lq]user\[rq] and \[lq]title\[rq] fields by +\f[CR]{user, title}\f[R]. +This is syntactic sugar for the filter +\f[CR]{user: .user, title: .title}\f[R], which uses the indexing +operator that we will see later. +.PP +When using a variable \f[CR]$x\f[R] as key without surrounding +parentheses, you can omit a value after \f[CR]$x\f[R], i.e.\ you can +write \f[CR]{$x}\f[R]. +This is equivalent to \f[CR]{x: $x}\f[R], which constructs an object +with a field \f[CR]\[dq]x\[dq]\f[R] that takes the value of +\f[CR]$x\f[R]. +.PP +When using a variable \f[CR]$x\f[R] as key and a value is given, +i.e.\ \f[CR]{$x: v}\f[R], then this is equivalent to +\f[CR]{($x): v}\f[R]. +.TP +\f[I]Example\f[R] +The filter +.IP +.EX +\[dq]f o o\[dq] as $foo | \[dq]b a r\[dq] as $bar | {$foo, $bar:$foo} +.EE +produces +.IP +.EX +{\[dq]foo\[dq]:\[dq]f o o\[dq],\[dq]b a r\[dq]:\[dq]f o o\[dq]} +.EE +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]{user, title: .titles[]}\[aq] \[rs] + <<< \[aq]{\[dq]user\[dq]:\[dq]stedolan\[dq],\[dq]titles\[dq]:[\[dq]JQ Primer\[dq], \[dq]More JQ\[dq]]}\[aq] +{\[dq]user\[dq]:\[dq]stedolan\[dq], \[dq]title\[dq]: \[dq]JQ Primer\[dq]} +{\[dq]user\[dq]:\[dq]stedolan\[dq], \[dq]title\[dq]: \[dq]More JQ\[dq]} +.EE +.IP +.EX +$ jq \[aq]{(.user): .titles}\[aq] \[rs] + <<< \[aq]{\[dq]user\[dq]:\[dq]stedolan\[dq],\[dq]titles\[dq]:[\[dq]JQ Primer\[dq], \[dq]More JQ\[dq]]}\[aq] +{\[dq]stedolan\[dq]: [\[dq]JQ Primer\[dq], \[dq]More JQ\[dq]]} +.EE +.IP +.EX +$ jq \[aq]{foo: .bar}\[aq] \[rs] + <<< \[aq]{\[dq]bar\[dq]:42, \[dq]baz\[dq]:43}\[aq] +{\[dq]foo\[dq]: 42}. +.EE +.SH BASIC FILTERS +.SS Identity: \f[CR].\f[R] +The simplest filter is \f[CR].\f[R] and is called the \f[I]identity +operator\f[R]. +This filter takes its input and produces the same value as output. +.PP +Since jq by default pretty\-prints all output, a trivial program +consisting of nothing but \f[CR].\f[R] can be used to format JSON output +from, say, \f[CR]curl\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].\[aq] \[rs] + <<< \[aq]\[dq]Hello, world!\[dq]\[aq] +\[dq]Hello, world!\[dq] +.EE +.IP +.EX +$ jq \[aq].\[aq] \[rs] + <<< \[aq]0.12345678901234567890123456789\[aq] +0.12345678901234567890123456789 +.EE +.SS Concatenation: \f[CR],\f[R] +The \f[CR],\f[R] operator concatenates the outputs of two filters. +.PP +Given two filters \f[CR]f\f[R] and \f[CR]g\f[R], their concatenation +\f[CR]f, g\f[R] first returns the outputs of \f[CR]f\f[R], then the +outputs of \f[CR]g\f[R]. +The input of \f[CR]f, g\f[R] is fed to both \f[CR]f\f[R] and +\f[CR]g\f[R]. +.TP +\f[I]Example\f[R] +The filter \f[CR].foo, .bar\f[R] produces both the \[lq]foo\[rq] fields +and \[lq]bar\[rq] fields as separate outputs. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].foo, .bar\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 42, \[dq]bar\[dq]: \[dq]something else\[dq], \[dq]baz\[dq]: true}\[aq] +42 +\[dq]something else\[dq] +.EE +.IP +.EX +$ jq \[aq].user, .projects[]\[aq] \[rs] + <<< \[aq]{\[dq]user\[dq]:\[dq]stedolan\[dq], \[dq]projects\[dq]: [\[dq]jq\[dq], \[dq]wikiflow\[dq]]}\[aq] +\[dq]stedolan\[dq] +\[dq]jq\[dq] +\[dq]wikiflow\[dq] +.EE +.IP +.EX +$ jq \[aq].[4,2]\[aq] \[rs] + <<< \[aq][\[dq]a\[dq],\[dq]b\[dq],\[dq]c\[dq],\[dq]d\[dq],\[dq]e\[dq]]\[aq] +\[dq]e\[dq] +\[dq]c\[dq] +.EE +.SS Composition: \f[CR]|\f[R] +The \f[CR]|\f[R] operator feeds the output of one filter to another +filter. +It\[cq]s similar to the Unix shell\[cq]s pipe, if you\[cq]re used to +that. +.PP +Given two filters \f[CR]f\f[R] and \f[CR]g\f[R], their composition +\f[CR]f | g\f[R] feeds the input of \f[CR]f | g\f[R] to \f[CR]f\f[R], +and for every output of \f[CR]f\f[R], feeds it to \f[CR]g\f[R] and +returns its outputs. +.TP +\f[I]Example\f[R] +The expression \f[CR].[] | .foo\f[R] retrieves the \[lq]foo\[rq] field +of each element of the input array. +.PP +Note too that \f[CR].\f[R] is the input value at the particular stage in +a \[lq]pipeline\[rq], specifically: where the \f[CR].\f[R] expression +appears. +Thus \f[CR].a | . | .b\f[R] is the same as \f[CR].a.b\f[R], as the +\f[CR].\f[R] in the middle refers to whatever value \f[CR].a\f[R] +produced. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[] | .name\[aq] \[rs] + <<< \[aq][{\[dq]name\[dq]:\[dq]JSON\[dq], \[dq]good\[dq]:true}, {\[dq]name\[dq]:\[dq]XML\[dq], \[dq]good\[dq]:false}]\[aq] +\[dq]JSON\[dq] +\[dq]XML\[dq] +.EE +.SS Function call +jq provides many builtin functions for a variety of tasks, and you can +also define your own functions. +.PP +Each function takes an input, as well as a fixed number of +\f[I]arguments\f[R]. +The number of arguments that a function takes is called \f[I]arity\f[R]. +For example, the function \f[CR]length\f[R] does not take any argument, +so its arity is 0, whereas the function \f[CR]contains\f[R] takes one +argument, so its arity is 1. +There may be several functions that have the same name, but different +arities; for example, there exist two functions called \f[CR]add\f[R], +taking zero and one arguments, respectively. +To unambiguously identify a function \f[CR]f\f[R] with arity +\f[CR]n\f[R], we write \f[CR]f/n\f[R], e.g.\ \f[CR]length/0\f[R], +\f[CR]contains/1\f[R], \f[CR]add/0\f[R], and \f[CR]add/1\f[R]. +.PP +To call a function \f[CR]f\f[R] with no arguments (arity 0), we write +\f[CR]f\f[R]. +To call a function \f[CR]f\f[R] with \f[CR]n\f[R] arguments (arity +greater than zero), we write \f[CR]f(a1; ...; an)\f[R]. +.TP +\f[I]Note\f[R] +Function calls use semicolons \f[CR];\f[R] instead of commas +\f[CR],\f[R] to separate arguments, because \f[CR],\f[R] is already used +for concatenation. +.TP +\f[I]Examples\f[R] +The first example calls the function \f[CR]length/0\f[R]: +.IP +.EX +$ jq \[aq]length\[aq] \[rs] + <<< \[aq][1, 1, 2, 3]\[aq] +4 +.EE +The next example calls \f[CR]range/2\f[R] and \f[CR]add/1\f[R]: +.IP +.EX +$ jq \[aq]add(range(0; .))\[aq] \[rs] + <<< \[aq]2\[aq] +3 +.EE +The last example calls \f[CR]while/2\f[R]: +.IP +.EX +$ jq \[aq]while(length < 3; . + \[dq]a\[dq])\[aq] \[rs] + <<< \[aq]\[dq]\[dq]\[aq] +\[dq]\[dq] +\[dq]a\[dq] +\[dq]aa\[dq] +.EE +.SS Parenthesis +Parentheses act as a grouping operator just as in any typical +programming language. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq](. + 2) * 5\[aq] \[rs] + <<< \[aq]1\[aq] +15 +.EE +.SS Recursive descent: \f[CR]..\f[R] +Recursively descends \f[CR].\f[R], producing every value. +This is the same as the zero\-argument \f[CR]recurse\f[R] function. +This is intended to resemble the XPath \f[CR]//\f[R] operator. +Note that \f[CR]..a\f[R] does not work; use \f[CR].. | .a\f[R] instead. +In the example below we use \f[CR].. | .a?\f[R] to find all the values +of object keys \[lq]a\[rq] in any object found \[lq]below\[rq] +\f[CR].\f[R]. +.PP +This is particularly useful in conjunction with \f[CR]path(EXP)\f[R] and +the \f[CR]?\f[R] operator. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].. | .a?\[aq] \[rs] + <<< \[aq][[{\[dq]a\[dq]:1}]]\[aq] +1 +.EE +.SH PATHS +In this section, we will show three very frequently used operators, +namely for iteration, indexing, and slicing. +These operators serve to obtain parts of values. +Furthermore, we will see how to combine these operators. +.SS Iteration operator: \f[CR].[]\f[R] +The operator \f[CR].[]\f[R] returns the values contained inside the +input value. +.PP +If the input is an array, then \f[CR].[]\f[R] returns all elements of +the array, and if the input is an object, \f[CR].[]\f[R] returns all the +values of the object. +For example, running \f[CR].[]\f[R] with the input \f[CR][1,2,3]\f[R] +produces the numbers \f[CR]1 2 3\f[R] as three separate results, rather +than as a single array. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[]\[aq] \[rs] + <<< \[aq][{\[dq]name\[dq]:\[dq]JSON\[dq], \[dq]good\[dq]:true}, {\[dq]name\[dq]:\[dq]XML\[dq], \[dq]good\[dq]:false}]\[aq] +{\[dq]name\[dq]:\[dq]JSON\[dq], \[dq]good\[dq]:true} +{\[dq]name\[dq]:\[dq]XML\[dq], \[dq]good\[dq]:false} +.EE +.IP +.EX +$ jq \[aq].[]\[aq] \[rs] + <<< \[aq][]\[aq] +.EE +.IP +.EX +$ jq \[aq].foo[]\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]:[1,2,3]}\[aq] +1 +2 +3 +.EE +.IP +.EX +$ jq \[aq].[]\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2}\[aq] +1 +2 +.EE +.SS Indexing operator: \f[CR].[f]\f[R] +When given an array as input, \f[CR].[n]\f[R] produces the +\f[CR]n\f[R]\-th element of the array. +For example, given the array \f[CR][2, 4, 6]\f[R], the filter +\f[CR].[1]\f[R] returns \f[CR]4\f[R]. +Arrays are zero\-based, so \f[CR].[2]\f[R] returns the third element. +Negative indices are allowed, with \-1 referring to the last element, +\-2 referring to the next to last element, and so on. +.PP +When given a JSON object as input, \f[CR].[k]\f[R] produces the value at +the key \f[CR]k\f[R] if it is present in the object, or \f[CR]null\f[R] +otherwise. +For example, given the object +\f[CR]{name: \[dq]Anna\[dq], age: 24}\f[R], the filter +\f[CR].[\[dq]name\[dq]]\f[R] produces \f[CR]\[dq]Anna\[dq]\f[R], +\f[CR].[\[dq]age\[dq]]\f[R] produces \f[CR]24\f[R], and +\f[CR].[\[dq]address\[dq]]\f[R] produces \f[CR]null\f[R]. +.PP +For identifier\-like keys like \f[CR]\[dq]foo\[dq]\f[R], you can also +look up the field \f[CR]\[dq]foo\[dq]\f[R] of an object using the +shorthand syntax \f[CR].foo\f[R]. +For example, we could have written \f[CR].name\f[R], \f[CR].age\f[R], +and \f[CR].address\f[R] above, whereas we cannot use this shorthand +syntax for \f[CR].[\[dq]foo::bar\[dq]]\f[R] and +\f[CR].[\[dq]foo.bar\[dq]]\f[R]. +.TP +\f[I]Compatibility\f[R] +In jq, when given \f[CR]null\f[R] input, \f[CR].[\[dq]a\[dq]]\f[R] and +\f[CR].[0]\f[R] yield \f[CR]null\f[R], but \f[CR].[]\f[R] yields an +error. +jaq yields an error in all cases to prevent accidental indexing of +\f[CR]null\f[R] values. +To obtain the same behaviour in jq and jaq, you can use +\f[CR].[\[dq]a\[dq]]? // null\f[R] or \f[CR].[0]? // null\f[R] instead. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].foo\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 42, \[dq]bar\[dq]: \[dq]less interesting data\[dq]}\[aq] +42 +.EE +.IP +.EX +$ jq \[aq].foo\[aq] \[rs] + <<< \[aq]{\[dq]notfoo\[dq]: true, \[dq]alsonotfoo\[dq]: false}\[aq] +null +.EE +.IP +.EX +$ jq \[aq].[\[dq]foo\[dq]]\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 42}\[aq] +42 +.EE +.IP +.EX +$ jq \[aq].[0]\[aq] \[rs] + <<< \[aq][{\[dq]name\[dq]:\[dq]JSON\[dq], \[dq]good\[dq]:true}, {\[dq]name\[dq]:\[dq]XML\[dq], \[dq]good\[dq]:false}]\[aq] +{\[dq]name\[dq]:\[dq]JSON\[dq], \[dq]good\[dq]:true} +.EE +.IP +.EX +$ jq \[aq].[2]\[aq] \[rs] + <<< \[aq][{\[dq]name\[dq]:\[dq]JSON\[dq], \[dq]good\[dq]:true}, {\[dq]name\[dq]:\[dq]XML\[dq], \[dq]good\[dq]:false}]\[aq] +null +.EE +.IP +.EX +$ jq \[aq].[\-2]\[aq] \[rs] + <<< \[aq][1,2,3]\[aq] +2 +.EE +.IP +.EX +$ jq \[aq]{a:1, b:2}\[aq] \[rs] + <<< \[aq].[\[dq]a\[dq],\[dq]b\[dq]]\[aq] +1 +2 +.EE +.IP +.EX +$ jq \[aq].[keys[] | select(test(\[dq]\[ha]b\[dq]))]\[aq] \[rs] + <<< \[aq]{a:1, b:2, c:3}\[aq] +2 +.EE +.SS Slicing operator: \f[CR].[f:g]\f[R] +The operator \f[CR].[f:g]\f[R] returns a slice of an array or a string. +For example, when given an array, \f[CR].[10:15]\f[R] returns an array +of length 5, containing the elements from index 10 (inclusive) to index +15 (exclusive). +Either index may be negative, in which case it counts backwards from the +end of the array. +If \f[CR]f\f[R] is omitted, it is assumed to be \f[CR]0\f[R], and if +\f[CR]g\f[R] is omitted, it is assumed to be \f[CR]length\f[R]. +Indices are zero\-based. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[2:4]\[aq] \[rs] + <<< \[aq][\[dq]a\[dq],\[dq]b\[dq],\[dq]c\[dq],\[dq]d\[dq],\[dq]e\[dq]]\[aq] +[\[dq]c\[dq], \[dq]d\[dq]] +.EE +.IP +.EX +$ jq \[aq].[2:4]\[aq] \[rs] + <<< \[aq]\[dq]abcdefghi\[dq]\[aq] +\[dq]cd\[dq] +.EE +.IP +.EX +$ jq \[aq].[:3]\[aq] \[rs] + <<< \[aq][\[dq]a\[dq],\[dq]b\[dq],\[dq]c\[dq],\[dq]d\[dq],\[dq]e\[dq]]\[aq] +[\[dq]a\[dq], \[dq]b\[dq], \[dq]c\[dq]] +.EE +.IP +.EX +$ jq \[aq].[\-2:]\[aq] \[rs] + <<< \[aq][\[dq]a\[dq],\[dq]b\[dq],\[dq]c\[dq],\[dq]d\[dq],\[dq]e\[dq]]\[aq] +[\[dq]d\[dq], \[dq]e\[dq]] +.EE +.IP +.EX +$ jq \[aq].[:range(1; length+1)]\[aq] \[rs] + <<< \[aq][1,2,3]\[aq] +[1] +[1,2] +[1,2,3] +.EE +.SS Compound paths +Frequently, when using the path operators given above, we find ourselves +combining them with the \f[CR]|\f[R] and \f[CR]?\f[R] operators. +Therefore, jq provides shorthand syntax for these combinations. +For example: +.IP \[bu] 2 +\f[CR].key[]\f[R] for \f[CR].key | .[]\f[R], +.IP \[bu] 2 +\f[CR].[].key?\f[R] for \f[CR].[] | .key?\f[R], +.IP \[bu] 2 +\f[CR].[]?[]\f[R] for \f[CR].[]? | .[]\f[R], +.IP \[bu] 2 +\f[CR].a.b\f[R] for \f[CR].a | .b\f[R], +.IP \[bu] 2 +\f[CR].a.b.c\f[R] for \f[CR].a | .b | .c\f[R], and so on. +.PP +We call such a combination a \f[I]compound path\f[R]. +.PP +The rules for what constitutes a compound path are surprisingly complex. +Therefore, we define it via a formal grammar in \c +.UR https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form +EBNF +.UE \c +: +.IP +.EX +path = atomic, part + | \[dq].\[dq], ident + | path, part + | path, part, \[dq]?\[dq] + ; + +part = \[dq].\[dq], ident + | \[dq][\[dq], \[dq]]\[dq] + | \[dq][\[dq], t, \[dq]]\[dq] + | \[dq][\[dq], t, \[dq]:\[dq], t, \[dq]]\[dq] + | \[dq][\[dq], t, \[dq]:\[dq], \[dq]]\[dq] + | \[dq][\[dq], \[dq]:\[dq], t, \[dq]]\[dq] + ; +.EE +.PP +Here, \f[CR]ident\f[R] refers to an identifier\-like key, \f[CR]t\f[R] +refers to a filter, and \f[CR]atomic\f[R] refers to an \f[I]atomic\f[R] +filter, such as \f[CR].\f[R] (identity), literal +(e.g.\ \f[CR]{a: 1}\f[R]), function call, and parenthesis. +This grammar defines a compound \f[CR]path\f[R] as a sequence of path +parts, potentially prefixed by an atomic root. +A path \f[CR]part\f[R] is any of the operators previously introduced in +this section. +(Note that \f[CR]part\f[R] does not include the leading \f[CR].\f[R] for +all operators except for \f[CR].ident\f[R].) +.TP +\f[I]Example\f[R] +The following is a compound path: +.IP +.EX +add[].posts[0]?.sections[][\[dq]title\[dq]]? +.EE +We can decompose it into its different parts: +.IP +.EX +add # atomic (function call) +[] # iteration +\&.posts # indexing +[0]? # indexing +\&.sections # indexing +[] # iteration +[\[dq]title\[dq]]? # indexing +.EE +We can transform this into an equivalent filter: +.IP +.EX + add +| .[] +| .posts +| .[0]? +| .sections +| .[] +| .[\[dq]title\[dq]]? +.EE +.PP +Filters inside a part of a compound path, such as \f[CR]f\f[R] and +\f[CR]g\f[R] in \f[CR].[f][:g]\f[R], are run with the \f[I]input given +to the whole path\f[R]. +.TP +\f[I]Example\f[R] +When we run the filter \f[CR].arr[][.key]\f[R] on the input +\f[CR]{key: \[dq]a\[dq], arr: [{a: 1, b: 2}, {a: 3}]}\f[R], then +\f[CR].key\f[R] is run on the original input, not on the current value +returned by \f[CR].arr[]\f[R]! +To see the difference, let us first consider a \f[B]wrong\f[R] +transformation: +.IP +.EX + .arr # \-\-> [{a: 1, b: 2}, {a: 3}] +| .[] # \-\-> {a: 1, b: 2}, {a: 3} +| .[.key] # \-\-> error (because .key is run with input {a: 1, b: 2} and yields null) +.EE +Now, let us consider a \f[B]correct\f[R] transformation: +.IP +.EX + .key as $x # \-\-> \[dq]a\[dq] +| .arr # \-\-> [{a: 1, b: 2}, {a: 3}] +| .[] # \-\-> {a: 1, b: 2}, {a: 3} +| .[$x] # \-\-> 1, 3 +.EE +.PP +When a path contains multiple filters, such as \f[CR].[f][g]\f[R], then +the filters are bound from \f[I]right to left\f[R]; that is, the filter +is equivalent to \f[CR]g as $y | f as $x | .[$x][$y]\f[R]. +This behaviour is similar to that of the arithmetic and comparison +operators. +However, for the slicing operator \f[CR].[f:g]\f[R], the filters are +bound from \f[I]left to right\f[R]; that is, the filter is equivalent to +\f[CR]f as $x | g as $y | .[$x:$y]\f[R]. +.TP +\f[I]Example\f[R] +Let us consider the input +\f[CR]{\[dq]a\[dq]: [1, 2], \[dq]b\[dq]: [3, 4]}\f[R] The filter +\f[CR].[\[dq]a\[dq], \[dq]b\[dq]][0, 1]\f[R] is equivalent to: +.IP +.EX +( 0 , 1 ) as $y | +(\[dq]a\[dq], \[dq]b\[dq]) as $x | +\&.[$x][$y] +.EE +Running it with the input yields \f[CR]1, 3, 2, 4\f[R]. +The filter \f[CR].[\[dq]a\[dq], \[dq]b\[dq]][0,1:1,2]\f[R] is equivalent +to: +.IP +.EX +( 0 , 1 ) as $y1 | +( 1 , 2 ) as $y2 | +(\[dq]a\[dq], \[dq]b\[dq]) as $x | +\&.[$x][$y1:$y2] +.EE +Running it with the input yields +\f[CR][1], [3], [1, 2], [3, 4], [], [], [2], [4]\f[R]. +.TP +\f[I]Compatibility\f[R] +In jaq, all filters in a path are bound \f[I]uniformly from left to +right\f[R]. +That is, the two examples above are equivalent to the filters +.IP +.EX +(\[dq]a\[dq], \[dq]b\[dq]) as $x | +( 0 , 1 ) as $y | +\&.[$x][$y] +.EE +yielding \f[CR]1, 2, 3, 4\f[R], and +.IP +.EX +(\[dq]a\[dq], \[dq]b\[dq]) as $x | +( 0 , 1 ) as $y1 | +( 1 , 2 ) as $y2 | +\&.[$x][$y1:$y2] +.EE +yielding \f[CR][1], [1, 2], [], [2], [3], [3, 4], [], [4]\f[R]. +.TP +\f[I]Note\f[R] +Surprisingly, the filter \f[CR].[f]?\f[R] is \f[B]not\f[R] equivalent to +\f[CR](.[f])?\f[R]. +To see this, let us transform \f[CR].[f]?\f[R] to an equivalent filter +like above: +.IP +.EX + f as $x +| .[$x]? +.EE +The difference shows when \f[CR]f\f[R] causes an error \[em] in that +case, \f[CR].[f]?\f[R] will raise the error, whereas \f[CR](.[f])?\f[R] +will not raise \f[I]any\f[R] error. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].foo?\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 42, \[dq]bar\[dq]: \[dq]less interesting data\[dq]}\[aq] +42 +.EE +.IP +.EX +$ jq \[aq].foo?\[aq] \[rs] + <<< \[aq]{\[dq]notfoo\[dq]: true, \[dq]alsonotfoo\[dq]: false}\[aq] +null +.EE +.IP +.EX +$ jq \[aq].[\[dq]foo\[dq]]?\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 42}\[aq] +42 +.EE +.IP +.EX +$ jq \[aq][.foo?]\[aq] \[rs] + <<< \[aq][1,2]\[aq] +[] +.EE +.SH ARITHMETIC AND COMPARISON +We are now going to introduce operators for arithmetic (\f[CR]+\f[R], +\f[CR]\-\f[R] \f[CR]*\f[R], \f[CR]/\f[R], \f[CR]%\f[R]), equality +(\f[CR]==\f[R], \f[CR]!=\f[R]), and ordering (\f[CR]<\f[R], +\f[CR]<=\f[R], \f[CR]>\f[R], \f[CR]>=\f[R]). +.PP +All operators in this section feed their input to both arguments and +combine their results. +This allows us to implement an averaging filter as +\f[CR]add / length\f[R] \[em] this feeds the input both to the +\f[CR]add\f[R] filter and the \f[CR]length\f[R] filter, then performs +the division of their results. +.PP +Given two filters \f[CR]f\f[R] and \f[CR]g\f[R], we can write +\f[CR]f + g\f[R], \f[CR]f == g\f[R], \f[CR]f < g\f[R] and so on to +perform the desired operation on the outputs of the filters \f[CR]f\f[R] +and \f[CR]g\f[R]. +When \f[CR]f\f[R] or \f[CR]g\f[R] outputs multiple values, then all +combinations of the operation are performed. +.TP +\f[I]Example\f[R] +Suppose that \f[CR]f\f[R] outputs the values \f[CR]1, 2\f[R] and +\f[CR]g\f[R] outputs the values \f[CR]3, 4\f[R]. +Then \f[CR]f * g\f[R] outputs the values \f[CR]3, 6, 4, 8\f[R]. +.TP +\f[I]Compatibility\f[R] +For any operator in this section such as \f[CR]+\f[R], in jq , +\f[CR]f + g\f[R] is equivalent to +\f[CR]g as $y | f as $x | $x + $y\f[R], whereas in jaq, \f[CR]f + g\f[R] +is equivalent to \f[CR]f as $x | g as $y | $x + $y\f[R]. +That means that in the above example, jaq outputs the values +\f[CR]3, 4, 6, 8\f[R] instead of \f[CR]3, 6, 4, 8\f[R]. +Note that this difference shows only when both \f[CR]f\f[R] and +\f[CR]g\f[R] produce multiple values. +.PP +Some jq operators (for instance, \f[CR]+\f[R]) do different things +depending on the type of their arguments (arrays, numbers, etc.). +However, jq never does implicit type conversions. +Trying to add a string to an object results in an error. +.SS Addition: \f[CR]+\f[R] +The operator \f[CR]+\f[R] takes two filters, applies them both to the +same input, and adds the results together. +What \[lq]adding\[rq] means depends on the types involved: +.IP \[bu] 2 +\f[B]Numbers\f[R] are added by normal arithmetic. +.IP \[bu] 2 +\f[B]Arrays\f[R] are added by being concatenated into a larger array. +.IP \[bu] 2 +\f[B]Strings\f[R] are added by being joined into a larger string. +.IP \[bu] 2 +\f[B]Objects\f[R] are added by merging, that is, inserting all the +key\-value pairs from both objects into a single combined object. +If both objects contain a value for the same key, the object on the +right of the \f[CR]+\f[R] wins. +(For recursive merge use the \f[CR]*\f[R] operator.) +.PP +\f[CR]null\f[R] can be added to any value, and returns the other value +unchanged. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].a + 1\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: 7}\[aq] +8 +.EE +.IP +.EX +$ jq \[aq].a + .b\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: [1,2], \[dq]b\[dq]: [3,4]}\[aq] +[1,2,3,4] +.EE +.IP +.EX +$ jq \[aq].a + null\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: 1}\[aq] +1 +.EE +.IP +.EX +$ jq \[aq].a + 1\[aq] \[rs] + <<< \[aq]{}\[aq] +1 +.EE +.IP +.EX +$ jq \[aq]{a: 1} + {b: 2} + {c: 3} + {a: 42}\[aq] \[rs] + <<< \[aq]null\[aq] +{\[dq]a\[dq]: 42, \[dq]b\[dq]: 2, \[dq]c\[dq]: 3} +.EE +.SS Subtraction: \f[CR]\-\f[R] +As well as normal arithmetic subtraction on numbers, the \f[CR]\-\f[R] +operator can be used on arrays to remove all occurrences of the second +array\[cq]s elements from the first array. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]4 \- .a\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]:3}\[aq] +1 +.EE +.IP +.EX +$ jq \[aq]. \- [\[dq]xml\[dq], \[dq]yaml\[dq]]\[aq] \[rs] + <<< \[aq][\[dq]xml\[dq], \[dq]yaml\[dq], \[dq]json\[dq]]\[aq] +[\[dq]json\[dq]] +.EE +.SS Multiplication, division, modulo: \f[CR]*\f[R], \f[CR]/\f[R], \f[CR]%\f[R] +These infix operators behave as expected when given two numbers. +Division by zero raises an error. +\f[CR]x % y\f[R] computes x modulo y. +.PP +Multiplying a string by a number produces the concatenation of that +string that many times. +\f[CR]\[dq]x\[dq] * 0\f[R] produces \f[CR]\[dq]\[dq]\f[R]. +.PP +Dividing a string by another splits the first using the second as +separators. +.PP +Multiplying two objects will merge them recursively: this works like +addition but if both objects contain a value for the same key, and the +values are objects, the two are merged with the same strategy. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]10 / . * 3\[aq] \[rs] + <<< \[aq]5\[aq] +6 +.EE +.IP +.EX +$ jq \[aq]. / \[dq], \[dq]\[aq] \[rs] + <<< \[aq]\[dq]a, b,c,d, e\[dq]\[aq] +[\[dq]a\[dq],\[dq]b,c,d\[dq],\[dq]e\[dq]] +.EE +.IP +.EX +$ jq \[aq]{\[dq]k\[dq]: {\[dq]a\[dq]: 1, \[dq]b\[dq]: 2}} * {\[dq]k\[dq]: {\[dq]a\[dq]: 0,\[dq]c\[dq]: 3}}\[aq] \[rs] + <<< \[aq]null\[aq] +{\[dq]k\[dq]: {\[dq]a\[dq]: 0, \[dq]b\[dq]: 2, \[dq]c\[dq]: 3}} +.EE +.IP +.EX +$ jq \[aq].[] | (1 / .)?\[aq] \[rs] + <<< \[aq][1,0,\-1]\[aq] +1 +\-1 +.EE +.SS Equality: \f[CR]==\f[R], \f[CR]!=\f[R] +The expression \f[CR]a == b\f[R] produces \f[CR]true\f[R] if the results +of evaluating \f[CR]a\f[R] and \f[CR]b\f[R] are equal (that is, if they +represent equivalent JSON values) and \f[CR]false\f[R] otherwise. +In particular, strings are never considered equal to numbers. +In checking for the equality of JSON objects, the ordering of keys is +irrelevant. +If you\[cq]re coming from JavaScript, please note that jq\[cq]s +\f[CR]==\f[R] is like JavaScript\[cq]s \f[CR]===\f[R], the \[lq]strict +equality\[rq] operator. +.PP +The expression \f[CR]a != b\f[R] returns \f[CR]false\f[R] if +\f[CR]a == b\f[R] returns \f[CR]true\f[R], else \f[CR]true\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]. == false\[aq] \[rs] + <<< \[aq]null\[aq] +false +.EE +.IP +.EX +$ jq \[aq]. == {\[dq]b\[dq]: {\[dq]d\[dq]: (4 + 1e\-20), \[dq]c\[dq]: 3}, \[dq]a\[dq]:1}\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]:1, \[dq]b\[dq]: {\[dq]c\[dq]: 3, \[dq]d\[dq]: 4}}\[aq] +true +.EE +.IP +.EX +$ jq \[aq].[] == 1\[aq] \[rs] + <<< \[aq][1, 1.0, \[dq]1\[dq], \[dq]banana\[dq]]\[aq] +true +true +false +false +.EE +.SS Ordering: \f[CR]>\f[R], \f[CR]>=\f[R], \f[CR]<=\f[R], \f[CR]<\f[R] +The ordering operators \f[CR]>\f[R], \f[CR]>=\f[R], \f[CR]<=\f[R], +\f[CR]<\f[R] return whether their left argument is greater than, greater +than or equal to, less than or equal to or less than their right +argument (respectively). +.PP +If two values of different type are ordered, the types are ordered +instead in the following increasing order: +.IP \[bu] 2 +\f[CR]null\f[R] +.IP \[bu] 2 +booleans +.IP \[bu] 2 +numbers +.IP \[bu] 2 +strings +.IP \[bu] 2 +arrays +.IP \[bu] 2 +objects +.PP +For booleans, \f[CR]false\f[R] is smaller than \f[CR]true\f[R]. +Strings are ordered \c +.UR https://en.wikipedia.org/wiki/Alphabetical_order +alphabetically +.UE \c +\ (by Unicode codepoint value). +Arrays are ordered \c +.UR https://en.wikipedia.org/wiki/Lexicographic_order +lexicographically +.UE \c +\&. +The ordering for objects is a little complex: first they\[cq]re compared +by comparing their sets of keys (as arrays in sorted order), and if +their keys are equal then the values are compared key by key. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]. < 5\[aq] \[rs] + <<< \[aq]2\[aq] +true +.EE +.IP +.EX +$ jq \[aq][1,3] > [1,2]\[aq] \[rs] + <<< \[aq]null\[aq] +true +.EE +.IP +.EX +$ jq \[aq]\[dq]jq\[dq] > false\[aq] \[rs] + <<< \[aq]null\[aq] +true +.EE +.SH BOOLEAN FILTERS +Every value can be converted to a boolean \[em] in particular, the +values \f[CR]false\f[R] and \f[CR]null\f[R] have the \f[I]boolean +value\f[R] \f[CR]false\f[R], all other values have the boolean value +\f[CR]true\f[R]. +This section describes several filters that analyze the boolean value of +values. +.PP +You can negate the boolean value of a value with the builtin function +\f[CR]not\f[R]. +It is called as a filter to which things can be piped rather than with +special syntax, as in \f[CR].foo and .bar | not\f[R]. +.TP +\f[I]Note\f[R] +Mind the precedences. +In particular, the filter \f[CR]false and false | not\f[R] is equivalent +to \f[CR](false and false) | not\f[R] and yields \f[CR]true\f[R], +whereas \f[CR]false and (false | not)\f[R] yields \f[CR]false\f[R]. +.SS if\-then\-else\-end +The filter \f[CR]if i then t else e end\f[R] runs \f[CR]t\f[R] when +\f[CR]i\f[R] returns an output with boolean value \f[CR]true\f[R], +otherwise, it runs \f[CR]e\f[R]. +.PP +Given three filters \f[CR]i\f[R], \f[CR]t\f[R], and \f[CR]e\f[R], the +expression \f[CR]if i then t else e end\f[R] runs \f[CR]i\f[R] on its +input. +For every value \f[CR]y\f[R] that is output by \f[CR]i\f[R], if +\f[CR]y\f[R] has the boolean value \f[CR]true\f[R] (that means, if +\f[CR]y\f[R] is neither \f[CR]false\f[R] nor \f[CR]null\f[R]), the +output of \f[CR]t\f[R] on the original input is produced, else the +output of \f[CR]e\f[R] on the original input is produced. +.TP +\f[I]Note\f[R] +Checking for false or null is a simpler notion of \[lq]truthiness\[rq] +than is found in JavaScript or Python, but it means that you\[cq]ll +sometimes have to be more explicit about the condition you want. +You can\[cq]t test whether, e.g.\ a string is empty using +\f[CR]if .name then A else B end\f[R]; you\[cq]ll need something like +\f[CR]if .name == \[dq]\[dq] then A else B end\f[R] instead. +.PP +More cases can be added to an if using \f[CR]elif A then B\f[R] syntax. +.PP +\f[CR]if A then B end\f[R] is shorthand for +\f[CR]if A then B else . end\f[R]. +That is, the \f[CR]else\f[R] branch is optional, and if absent, it is +the same as \f[CR].\f[R]. +This also applies to \f[CR]elif\f[R] with absent ending \f[CR]else\f[R] +branch. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]if . == 0 then \[dq]zero\[dq] elif . == 1 then \[dq]one\[dq] else \[dq]many\[dq] end\[aq] \[rs] + <<< \[aq]2\[aq] +\[dq]many\[dq] +.EE +.IP +.EX +$ jq \[aq].[] | if . then ., .+1 else . end\[aq] \[rs] + <<< \[aq][false, 1, null]\[aq] +false +1 +2 +null +.EE +.IP +.EX +$ jq \[aq]if range(0;4) % 2 == 0 then \[dq]even\[dq] else \[dq]odd\[dq] end\[aq] \[rs] + <<< \[aq]null\[aq] +\[dq]even\[dq] +\[dq]odd\[dq] +\[dq]even\[dq] +\[dq]odd\[dq] +.EE +.SS \f[CR]and\f[R], \f[CR]or\f[R] +The filter \f[CR]f and g\f[R] returns true if both \f[CR]f\f[R] and +\f[CR]g\f[R] return an output with boolean value \f[CR]true\f[R]. +The filter \f[CR]f or g\f[R] returns true if either \f[CR]f\f[R] or +\f[CR]g\f[R] return an output with boolean value \f[CR]true\f[R]. +Otherwise, both filters return \f[CR]false\f[R]. +.PP +Given two filters \f[CR]f\f[R] and \f[CR]g\f[R], their conjunction +\f[CR]f and g\f[R] and their disjunction \f[CR]f or g\f[R] run +\f[CR]f\f[R] on the input, and for every output \f[CR]y\f[R] of +\f[CR]f\f[R], they analyze the boolean value \f[CR]y\f[R] of the output: +.IP \[bu] 2 +\f[CR]f and g\f[R] yields \f[CR]false\f[R] if \f[CR]y\f[R] is +\f[CR]false\f[R], otherwise it runs \f[CR]g\f[R] with the original input +and yields the boolean values of its outputs. +.IP \[bu] 2 +\f[CR]f or g\f[R] yields \f[CR]true\f[R] if \f[CR]y\f[R] is +\f[CR]true\f[R], otherwise it runs \f[CR]g\f[R] with the original input +and yields the boolean values of its outputs. +.TP +\f[I]Example\f[R] +The filter \f[CR]true and false\f[R] returns \f[CR]false\f[R], whereas +\f[CR]true or false\f[R] returns \f[CR]true\f[R]. +.TP +\f[I]Note\f[R] +These filters only produce the values \f[CR]true\f[R] and +\f[CR]false\f[R], rather than the common Perl/Python/Ruby idiom of +\[lq]value_that_may_be_null or default\[rq]. +If you want to use this form of \[lq]or\[rq], picking between two values +rather than evaluating a condition, see the \f[CR]//\f[R] operator +below. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]42 and \[dq]a string\[dq]\[aq] \[rs] + <<< \[aq]null\[aq] +true +.EE +.IP +.EX +$ jq \[aq](true, false) or false\[aq] \[rs] + <<< \[aq]null\[aq] +true +false +.EE +.IP +.EX +$ jq \[aq](true, true) and (true, false)\[aq] \[rs] + <<< \[aq]null\[aq] +true +false +true +false +.EE +.IP +.EX +$ jq \[aq][true, false | not]\[aq] \[rs] + <<< \[aq]null\[aq] +[false, true] +.EE +.SS Alternative operator: \f[CR]//\f[R] +Given two filters \f[CR]f\f[R] and \f[CR]g\f[R], the filter +\f[CR]f // g\f[R] runs \f[CR]f\f[R] on the input and yields all of its +outputs whose boolean value is \f[CR]true\f[R]. +If the boolean values of all outputs of \f[CR]f\f[R] are +\f[CR]false\f[R] (which is also the case if \f[CR]f\f[R] does not yield +any output at all), then \f[CR]f // g\f[R] runs \f[CR]g\f[R] with the +original input and yields its outputs. +.PP +This is useful for providing defaults: \f[CR].foo // 1\f[R] evaluates to +\f[CR]1\f[R] if there\[cq]s no \f[CR].foo\f[R] element in the input. +It\[cq]s similar to how \f[CR]or\f[R] is sometimes used in Python +(jq\[cq]s \f[CR]or\f[R] operator is reserved for strictly Boolean +operations). +.TP +\f[I]Note\f[R] +\f[CR]f // g\f[R] is not the same as \f[CR]f | (. // g)\f[R] (which can +be written more compactly as \f[CR]f | . // g\f[R]). +The latter produces default values for \f[I]all\f[R] outputs of +\f[CR]f\f[R] whose boolean value is \f[CR]false\f[R], while the former +does not. +.TP +\f[I]Example\f[R] +The filter \f[CR](false, null, 1) | . // 42\f[R] yields the outputs +\f[CR]42, 42, 1\f[R], whereas the filter +\f[CR](false, null, 1) // 42\f[R] yields just \f[CR]1\f[R]. +.TP +\f[I]Note\f[R] +Mind the precedence rules. +For example, in \f[CR]false, 1 // 2\f[R] the left\-hand side of +\f[CR]//\f[R] is \f[CR]1\f[R], not \f[CR]false, 1\f[R]. +This is because \f[CR]false, 1 // 2\f[R] parses the same way as +\f[CR]false, (1 // 2)\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]empty // 42\[aq] \[rs] + <<< \[aq]null\[aq] +42 +.EE +.IP +.EX +$ jq \[aq].foo // 42\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 19}\[aq] +19 +.EE +.IP +.EX +$ jq \[aq].foo // 42\[aq] \[rs] + <<< \[aq]{}\[aq] +42 +.EE +.IP +.EX +$ jq \[aq](false, null, 1) // 42\[aq] \[rs] + <<< \[aq]null\[aq] +1 +.EE +.IP +.EX +$ jq \[aq](false, null, 1) | . // 42\[aq] \[rs] + <<< \[aq]null\[aq] +42 +42 +1 +.EE +.SH ERROR HANDLING +Many filters throw errors, e.g.\ \f[CR]0 | .[]\f[R] or \f[CR]error\f[R]. +In this section, we show how to recover from errors. +.SS try\-catch +Errors can be caught by using \f[CR]try EXP catch EXP\f[R]. +The first expression is executed, and if it fails, then the second is +executed with the error message. +The output of the handler, if any, is output as if it had been the +output of the expression to try. +.PP +The \f[CR]try EXP\f[R] form uses \f[CR]empty\f[R] as the exception +handler. +.PP +Using try/catch allows to break out of control structures like +\f[CR]reduce\f[R], \f[CR]foreach\f[R], \f[CR]while\f[R], and so on. +For a more robust way to do this, you may also use +\f[CR]label\-break\f[R]. +.TP +\f[I]Example\f[R] +The following filter repeats an expression \f[CR]exp\f[R] until it +raises an error. +If the error is \[lq]break\[rq], then this stops repeating without +re\-raising the error. +If the error is something else, then this re\-raises it. +.IP +.EX +try repeat(exp) catch if .==\[dq]break\[dq] then empty else error +.EE +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]try .a catch \[dq]. is not an object\[dq]\[aq] \[rs] + <<< \[aq]true\[aq] +\[dq]. is not an object\[dq] +.EE +.IP +.EX +$ jq \[aq][.[]|try .a]\[aq] \[rs] + <<< \[aq][{}, true, {\[dq]a\[dq]:1}]\[aq] +[null, 1] +.EE +.IP +.EX +$ jq \[aq]try error(\[dq]some exception\[dq]) catch .\[aq] \[rs] + <<< \[aq]true\[aq] +\[dq]some exception\[dq] +.EE +.SS Error suppression: \f[CR]?\f[R] +The \f[CR]?\f[R] operator, used as \f[CR]f?\f[R], is shorthand for +\f[CR]try f\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][.[] | .a?]\[aq] \[rs] + <<< \[aq][{}, true, {\[dq]a\[dq]:1}]\[aq] +[null, 1] +.EE +.IP +.EX +$ jq \[aq][.[] | tonumber?]\[aq] \[rs] + <<< \[aq][\[dq]1\[dq], \[dq]invalid\[dq], \[dq]3\[dq], 4]\[aq] +[1, 3, 4] +.EE +.SS label\-break +jq has a syntax for named lexical labels to \[lq]break\[rq] or \[lq]go +(back) to\[rq]: +.IP +.EX +label $out | ... break $out ... +.EE +.PP +The \f[CR]break $label_name\f[R] expression will cause the program to +act as though the nearest (to the left) \f[CR]label $label_name\f[R] +produced \f[CR]empty\f[R]. +.PP +The relationship between the \f[CR]break\f[R] and corresponding +\f[CR]label\f[R] is lexical: the label has to be \[lq]visible\[rq] from +the break. +.PP +To break out of a \f[CR]reduce\f[R], for example: +.IP +.EX +label $out | reduce .[] as $item (null; if .==false then break $out else ... end) +.EE +.PP +The following jq program produces a syntax error: +.IP +.EX +break $out +.EE +.PP +because no label \f[CR]$out\f[R] is visible. +.SH VARIABLES +Variables are an absolute necessity in most programming languages, but +in jq, they can be considered an \[lq]advanced feature\[rq]. +.PP +In most languages, variables are the only means of passing around data. +If you calculate a value, and you want to use it more than once, +you\[cq]ll need to store it in a variable. +To pass a value to another part of the program, you\[cq]ll need that +part of the program to define a variable (as a function parameter, +object member, or whatever) in which to place the data. +.PP +It is also possible to define functions in jq itself. +In fact, many of jq\[cq]s built\-in functions, including \f[CR]map\f[R] +and \f[CR]select\f[R], are written in jq. +.SS Variable binding: \f[CR]f as $x | g\f[R] +In jq, all filters have an input and an output, so manual plumbing is +not necessary to pass a value from one part of a program to the next. +Many expressions, for instance \f[CR]a + b\f[R], pass their input to two +distinct subexpressions (here \f[CR]a\f[R] and \f[CR]b\f[R] are both +passed the same input), so variables aren\[cq]t usually necessary in +order to use a value twice. +.PP +For instance, calculating the average value of an array of numbers +requires a few variables in most languages \- at least one to hold the +array, perhaps one for each element or for a loop counter. +In jq, it\[cq]s simply \f[CR]add / length\f[R] \- the \f[CR]add\f[R] +expression is given the array and produces its sum, and the +\f[CR]length\f[R] expression is given the array and produces its length. +.PP +So, variables are often unnecessary and sometimes even best avoided, but +jq does let you define variables using the syntax \f[CR]f as $x\f[R]. +All variable names start with \f[CR]$\f[R]. +Here\[cq]s a slightly uglier version of the array\-averaging example: +.IP +.EX +length as $array_length | add / $array_length +.EE +.PP +We\[cq]ll need a more complicated problem to find a situation where +using variables actually makes our lives easier. +.TP +\f[I]Example\f[R] +Suppose we have an array of blog posts, with \[lq]author\[rq] and +\[lq]title\[rq] fields, and another object which is used to map author +usernames to real names. +Our input looks like: +.IP +.EX +{\[dq]posts\[dq]: [{\[dq]title\[dq]: \[dq]First post\[dq], \[dq]author\[dq]: \[dq]anon\[dq]}, + {\[dq]title\[dq]: \[dq]A well\-written article\[dq], \[dq]author\[dq]: \[dq]person1\[dq]}], + \[dq]realnames\[dq]: {\[dq]anon\[dq]: \[dq]Anonymous Coward\[dq], + \[dq]person1\[dq]: \[dq]Person McPherson\[dq]}} +.EE +We want to produce the posts with the author field containing a real +name, as in: +.IP +.EX +{\[dq]title\[dq]: \[dq]First post\[dq], \[dq]author\[dq]: \[dq]Anonymous Coward\[dq]} +{\[dq]title\[dq]: \[dq]A well\-written article\[dq], \[dq]author\[dq]: \[dq]Person McPherson\[dq]} +.EE +We use a variable, \f[CR]$names\f[R], to store the realnames object, so +that we can refer to it later when looking up author usernames: +.IP +.EX +\&.realnames as $names | .posts[] | {title, author: $names[.author]} +.EE +.PP +The filter \f[CR]f as $x | g\f[R] runs \f[CR]f\f[R] on its input, and +for each output \f[CR]y\f[R] produced by \f[CR]f\f[R], it runs +\f[CR]g\f[R] with the original input and with \f[CR]$x\f[R] set to +\f[CR]y\f[R]. +Thus \f[CR]as\f[R] functions as something of a foreach loop. +.PP +You can write \f[CR]{$foo}\f[R] as shorthand for \f[CR]{foo: $foo}\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].bar as $x | .foo | . + $x\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]:10, \[dq]bar\[dq]:200}\[aq] +210 +.EE +.IP +.EX +$ jq \[aq]. as $i|[(.*2|. as $i| $i), $i]\[aq] \[rs] + <<< \[aq]5\[aq] +[10,5] +.EE +.SS Scoping +There are three types of symbols in jq: variables, labels, and +functions. +All of these symbols are scoped lexically, with filters being able to +refer only to symbols that have been defined \[lq]to the left\[rq] of +them. +Furthermore, there is no way to change the value of a binding; one can +only create a new binding with the same name, but this will not be +visible where the old one was. +.TP +\f[I]Example\f[R] +In the filter +.IP +.EX +\&.realnames as $names | (.posts[] | {title, author: $names[.author]}) +.EE +the binding \f[CR]$names\f[R] is visible \[lq]to the right\[rq] of it, +but in the filter +.IP +.EX +(.realnames as $names | .posts[]) | {title, author: $names[.author]} +.EE +the binding \f[CR]$names\f[R] is \f[I]not\f[R] visible past the closing +parenthesis, so the filter is not well\-formed. +.TP +\f[I]Example\f[R] +The filter \f[CR]1 as $x | (2 as $x | $x), $x\f[R] returns the values +\f[CR]2, 1\f[R]. +First, it introduces a variable \f[CR]$x\f[R] via \f[CR]1 as $x\f[R], +then it introduces a variable \f[CR]$x\f[R] via \f[CR]2 as $x\f[R] that +\f[I]shadows\f[R] the previous \f[CR]$x\f[R]. +However, because we limit the scope of \f[CR]2 as $x\f[R] with +parentheses, the final \f[CR]$x\f[R] refers to the original +\f[CR]1 as $x\f[R] again. +.TP +\f[I]Note\f[R] +Labels and variables look alike, yet they live in different worlds. +To see this, consider the filter +\f[CR]1 as $x | label $x | $x, break $x, 2\f[R]. +If the variable \f[CR]$x\f[R] and the label \f[CR]$x\f[R] would live in +the same world, then the label \f[CR]$x\f[R] would shadow the variable +\f[CR]$x\f[R]. +However, because they live in different worlds, they do not shadow each +other, therefore this filter is syntactically correct and returns +\f[CR]1\f[R]. +.SS Destructuring +So far in this section, every variable binding \f[CR]f as $x | g\f[R] +bound exactly one variable \f[CR]$x\f[R] in \f[CR]g\f[R]. +Now, we will introduce a mechanism to bind \f[I]multiple\f[R] variables +in one \f[CR]as\f[R] binding. +For this, we write \f[CR]f as p | g\f[R], where \f[CR]p\f[R] is a +\f[I]pattern\f[R] that matches the structure of the outputs of +\f[CR]f\f[R]. +.TP +\f[I]Example\f[R] +The filter +.IP +.EX +\&. as {realnames: $names, posts: [$first, $second]} | g +.EE +is equivalent to the filter +.IP +.EX +\&.realnames as $names | +\&.posts[0] as $first | +\&.posts[1] as $second | +g +.EE +.PP +The variable declarations in array patterns (e.g., +\f[CR]. as [$first, $second]\f[R]) bind the elements of the array from +the element at index zero on up, in order. +When there is no value at the index for an array pattern element, +\f[CR]null\f[R] is bound to that variable. +.TP +\f[I]Example\f[R] +The filter +.IP +.EX +\&. as [$x, {a: $y}] | $x, $y +.EE +is equivalent to the filter +.IP +.EX +\&.[0] as $x | +\&.[1] as $p1 | +$p1.a as $y | +$x, $y +.EE +Given the input \f[CR]{a: 1, b: []}\f[R], it returns twice +\f[CR]null\f[R], because neither \f[CR].b\f[R] nor \f[CR].c[0]\f[R] are +present in the input. +.PP +Similarly to object construction, \f[CR]{$x}\f[R] is equivalent to +\f[CR]{x: $x}\f[R] also for object patterns. +.TP +\f[I]Example\f[R] +We could have written the previous example equivalently as: +.IP +.EX +\&. as [$x, {$a}] | $x, $a +.EE +.PP +We can write any filter \f[CR](f)\f[R] as object key in a pattern. +.TP +\f[I]Example\f[R] +Given the input +\f[CR]{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2, \[dq]c\[dq]: 3, \[dq]d\[dq]: 4}\f[R], +the filter +.IP +.EX +\&. as {(\[dq]a\[dq], \[dq]b\[dq]): $x, (\[dq]c\[dq], \[dq]d\[dq]): $y} | [$x, $y] +.EE +produces four outputs, namely \f[CR][1, 3] [1, 4] [2, 3] [2, 4]\f[R]. +.PP +When using a filter \f[CR](f)\f[R] as object key in a pattern, then +\f[CR]f\f[R] is run with the input that was matched by its parent object +pattern, not by the whole pattern. +.TP +\f[I]Example\f[R] +The filter +.IP +.EX + . as [{(.k): $x}] | $x +.EE +is equivalent to: +.IP +.EX +\&.[0] as $p0 | +$p0.k as $x | +$x +.EE +Here, we can see that \f[CR](.k)\f[R] is run with the input +\f[CR]$p0\f[R], which is the value that the parent object pattern of +\f[CR](.k)\f[R], namely \f[CR]{(.k): $x}\f[R], is trying to match. +Compare this with the following \f[I]wrong\f[R] transformation, where +\f[CR](.k)\f[R] would be run with the input matched by the whole +pattern: +.IP +.EX +\&.[0] as $p0 | +\&.k as $x | +$x +.EE +Given the input \f[CR][{\[dq]k\[dq]: \[dq]a\[dq], \[dq]a\[dq]: 1}]\f[R], +the first (correct) transformation yields \f[CR]1\f[R], whereas the +second (wrong) transformation yields an error. +.PP +We can also use patterns in reduction operators such as +\f[CR]reduce\f[R] and \f[CR]foreach\f[R]. +.TP +\f[I]Note\f[R] +A pattern \f[CR]p\f[R] is either a variable \f[CR]$x\f[R], an array +pattern \f[CR][p1, ..., pn]\f[R] containing \f[CR]n\f[R] patterns, or an +object pattern \f[CR]{e1, ..., en}\f[R] containing \f[CR]n\f[R] object +entries. +An object entry \f[CR]e\f[R] is either a variable \f[CR]$x\f[R] or a +key\-value pair \f[CR](f): g\f[R] (where \f[CR]f\f[R] and \f[CR]g\f[R] +are filters). +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]. as [$a, $b, {c: $c}] | $a + $b + $c\[aq] \[rs] + <<< \[aq][2, 3, {\[dq]c\[dq]: 4, \[dq]d\[dq]: 5}]\[aq] +9 +.EE +.IP +.EX +$ jq \[aq].[] as [$a, $b] | {a: $a, b: $b}\[aq] \[rs] + <<< \[aq][[0], [0, 1], [2, 1, 0]]\[aq] +{\[dq]a\[dq]:0,\[dq]b\[dq]:null} +{\[dq]a\[dq]:0,\[dq]b\[dq]:1} +{\[dq]a\[dq]:2,\[dq]b\[dq]:1} +.EE +.IP +.EX +$ jq \[aq]foreach .[] as {(\[dq]a\[dq], \[dq]b\[dq]): $x} ([]; . + [$x])\[aq] \[rs] + <<< \[aq][{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2}, {\[dq]a\[dq]: 3, \[dq]b\[dq]: 4}]\[aq] +[1] +[1,2] +[1,2,3] +[1,2,3,4] +.EE +.SS Destructuring alternative operator: \f[CR]?//\f[R] +The destructuring alternative operator provides a concise mechanism for +destructuring an input that can take one of several forms. +.PP +Suppose we have an API that returns a list of resources and events +associated with them, and we want to get the user_id and timestamp of +the first event for each resource. +The API (having been clumsily converted from XML) will only wrap the +events in an array if the resource has multiple events: +.IP +.EX +{\[dq]resources\[dq]: [ + {\[dq]id\[dq]: 1, \[dq]kind\[dq]: \[dq]widget\[dq], \[dq]events\[dq]: {\[dq]action\[dq]: \[dq]create\[dq], \[dq]user_id\[dq]: 1, \[dq]ts\[dq]: 13}}, + {\[dq]id\[dq]: 2, \[dq]kind\[dq]: \[dq]widget\[dq], \[dq]events\[dq]: [ + {\[dq]action\[dq]: \[dq]create\[dq], \[dq]user_id\[dq]: 1, \[dq]ts\[dq]: 14}, + {\[dq]action\[dq]: \[dq]destroy\[dq], \[dq]user_id\[dq]: 1, \[dq]ts\[dq]: 15} + ]} +]} +.EE +.PP +We can use the destructuring alternative operator to handle this +structural change simply: +.IP +.EX +\&.resources[] as {$id, $kind, events: {$user_id, $ts}} ?// {$id, $kind, events: [{$user_id, $ts}]} | +{$user_id, $kind, $id, $ts} +.EE +.PP +Or, if we aren\[cq]t sure if the input is an array of values or an +object: +.IP +.EX +\&.[] as [$id, $kind, $user_id, $ts] ?// {$id, $kind, $user_id, $ts} | ... +.EE +.PP +Each alternative need not define all of the same variables, but all +named variables will be available to the subsequent expression. +Variables not matched in the alternative that succeeded will be +\f[CR]null\f[R]: +.IP +.EX +\&.resources[] as {$id, $kind, events: {$user_id, $ts}} ?// {$id, $kind, events: [{$first_user_id, $first_ts}]} | +{$user_id, $first_user_id, $kind, $id, $ts, $first_ts} +.EE +.PP +Additionally, if the subsequent expression returns an error, the +alternative operator will attempt to try the next binding. +Errors that occur during the final alternative are passed through. +.IP +.EX +[[3]] | .[] as [$a] ?// [$b] | if $a != null then error(\[dq]err: \[rs]($a)\[dq]) else {$a,$b} end +.EE +.TP +\f[I]Compatibility\f[R] +jaq does not support this operator. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[] as {$a, $b, c: {$d, $e}} ?// {$a, $b, c: [{$d, $e}]} | {$a, $b, $d, $e}\[aq] \[rs] + <<< \[aq][{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2, \[dq]c\[dq]: {\[dq]d\[dq]: 3, \[dq]e\[dq]: 4}}, {\[dq]a\[dq]: 1, \[dq]b\[dq]: 2, \[dq]c\[dq]: [{\[dq]d\[dq]: 3, \[dq]e\[dq]: 4}]}]\[aq] +{\[dq]a\[dq]:1,\[dq]b\[dq]:2,\[dq]d\[dq]:3,\[dq]e\[dq]:4} +{\[dq]a\[dq]:1,\[dq]b\[dq]:2,\[dq]d\[dq]:3,\[dq]e\[dq]:4} +.EE +.IP +.EX +$ jq \[aq].[] as {$a, $b, c: {$d}} ?// {$a, $b, c: [{$e}]} | {$a, $b, $d, $e}\[aq] \[rs] + <<< \[aq][{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2, \[dq]c\[dq]: {\[dq]d\[dq]: 3, \[dq]e\[dq]: 4}}, {\[dq]a\[dq]: 1, \[dq]b\[dq]: 2, \[dq]c\[dq]: [{\[dq]d\[dq]: 3, \[dq]e\[dq]: 4}]}]\[aq] +{\[dq]a\[dq]:1,\[dq]b\[dq]:2,\[dq]d\[dq]:3,\[dq]e\[dq]:null} +{\[dq]a\[dq]:1,\[dq]b\[dq]:2,\[dq]d\[dq]:null,\[dq]e\[dq]:4} +.EE +.IP +.EX +$ jq \[aq].[] as [$a] ?// [$b] | if $a != null then error(\[dq]err: \[rs]($a)\[dq]) else {$a,$b} end\[aq] \[rs] + <<< \[aq][[3]]\[aq] +{\[dq]a\[dq]:null,\[dq]b\[dq]:3} +.EE +.SH REDUCTION +jq has reduction operators, which can be used to run a filter on every +element of a stream while keeping some intermediate state. +These operators are used to define some bits of jq\[cq]s standard +library, such as \f[CR]add\f[R]. +.SS \f[CR]reduce\f[R] +The \f[CR]reduce\f[R] syntax allows you to combine all of the results of +an expression by accumulating them into a single answer. +The form is \f[CR]reduce EXP as $var (INIT; UPDATE)\f[R]. +As an example, we\[cq]ll pass \f[CR][1,2,3]\f[R] to this expression: +.IP +.EX +reduce .[] as $item (0; . + $item) +.EE +.PP +For each result that \f[CR].[]\f[R] produces, \f[CR]. + $item\f[R] is +run to accumulate a running total, starting from 0 as the input value. +In this example, \f[CR].[]\f[R] produces the results \f[CR]1\f[R], +\f[CR]2\f[R], and \f[CR]3\f[R], so the effect is similar to running +something like this: +.IP +.EX +0 | 1 as $item | . + $item | + 2 as $item | . + $item | + 3 as $item | . + $item +.EE +.TP +\f[I]Compatibility\f[R] +When \f[CR]UPDATE\f[R] yields multiple outputs, jq only considers the +\f[I]last\f[R] one for the next iteration, whereas jaq considers +\f[I]all\f[R] of them. +For example, the filter +.IP +.EX +reduce (0, 1) as $x ([]; . + ([\[dq]a\[dq], $x], [\[dq]b\[dq], $x])) +.EE +yields \f[CR][\[dq]b\[dq],0,\[dq]b\[dq],1]\f[R] in jq, whereas in jaq, +it yields: +.IP +.EX +[\[dq]a\[dq],0,\[dq]a\[dq],1] +[\[dq]a\[dq],0,\[dq]b\[dq],1] +[\[dq]b\[dq],0,\[dq]a\[dq],1] +[\[dq]b\[dq],0,\[dq]b\[dq],1] +.EE +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]reduce .[] as $item (0; . + $item)\[aq] \[rs] + <<< \[aq][1,2,3,4,5]\[aq] +15 +.EE +.IP +.EX +$ jq \[aq]reduce .[] as [$i,$j] (0; . + $i * $j)\[aq] \[rs] + <<< \[aq][[1,2],[3,4],[5,6]]\[aq] +44 +.EE +.IP +.EX +$ jq \[aq]reduce .[] as {$x,$y} (null; .x += $x | .y += [$y])\[aq] \[rs] + <<< \[aq][{\[dq]x\[dq]:\[dq]a\[dq],\[dq]y\[dq]:1},{\[dq]x\[dq]:\[dq]b\[dq],\[dq]y\[dq]:2},{\[dq]x\[dq]:\[dq]c\[dq],\[dq]y\[dq]:3}]\[aq] +{\[dq]x\[dq]:\[dq]abc\[dq],\[dq]y\[dq]:[1,2,3]} +.EE +.SS \f[CR]foreach\f[R] +The \f[CR]foreach\f[R] syntax is similar to \f[CR]reduce\f[R], but +intended to allow the construction of \f[CR]limit\f[R] and reducers that +produce intermediate results. +.PP +The form is \f[CR]foreach EXP as $var (INIT; UPDATE; EXTRACT)\f[R]. +As an example, we\[cq]ll pass \f[CR][1,2,3]\f[R] to this expression: +.IP +.EX +foreach .[] as $item (0; . + $item; [$item, . * 2]) +.EE +.PP +Like the \f[CR]reduce\f[R] syntax, \f[CR]. + $item\f[R] is run for each +result that \f[CR].[]\f[R] produces, but \f[CR][$item, . * 2]\f[R] is +run for each intermediate values. +In this example, since the intermediate values are \f[CR]1\f[R], +\f[CR]3\f[R], and \f[CR]6\f[R], the \f[CR]foreach\f[R] expression +produces \f[CR][1,2]\f[R], \f[CR][2,6]\f[R], and \f[CR][3,12]\f[R]. +So the effect is similar to running something like this: +.IP +.EX +0 | 1 as $item | . + $item | [$item, . * 2], + 2 as $item | . + $item | [$item, . * 2], + 3 as $item | . + $item | [$item, . * 2] +.EE +.PP +When \f[CR]EXTRACT\f[R] is omitted, the identity filter is used. +That is, it outputs the intermediate values as they are. +.TP +\f[I]Note\f[R] +We can also use a pattern at the place of \f[CR]$var\f[R]. +.IP +.EX +foreach EXP as PATTERN (INIT; UPDATE; EXTRACT) +.EE +When \f[CR]PATTERN\f[R] binds the variables \f[CR]$x1\f[R], \&..., +\f[CR]$xn\f[R], then the expression is equivalent to: +.IP +.EX +foreach (EXP as PATTERN | {$x1, ..., $xn}) as $x ( + INIT; + $x as {$x1, ..., $xn} | UPDATE; + $x as {$x1, ..., $xn} | EXTRACT +) +.EE +(Here, the name of \f[CR]$x\f[R] must be chosen such that \f[CR]$x\f[R] +does not shadow any existing variable at this point.) +A similar transformation can be made for \f[CR]reduce\f[R]. +.TP +\f[I]Compatibility\f[R] +Similarly as for \f[CR]reduce\f[R], jq considers only the \f[I]last\f[R] +output of \f[CR]UPDATE\f[R] for the next iteration, whereas jaq +considers \f[I]all\f[R] of them. +For example, the filter +.IP +.EX +foreach (0, 1) as $x ([]; . + ([\[dq]a\[dq], $x], [\[dq]b\[dq], $x])) +.EE +yields +.IP +.EX +[\[dq]a\[dq],0] +[\[dq]b\[dq],0] +[\[dq]b\[dq],0,\[dq]a\[dq],1] +[\[dq]b\[dq],0,\[dq]b\[dq],1] +.EE +in jq. +Here, we can see that jq actually yields both outputs of +\f[CR]UPDATE\f[R], namely \f[CR][\[dq]a\[dq],0]\f[R] and +\f[CR][\[dq]b\[dq],0]\f[R], but it only uses the last of them, namely +\f[CR][\[dq]b\[dq],0]\f[R], for the second iteration. +In contrast, jaq yields: +.IP +.EX +[\[dq]a\[dq],0] +[\[dq]a\[dq],0,\[dq]a\[dq],1] +[\[dq]a\[dq],0,\[dq]b\[dq],1] +[\[dq]b\[dq],0] +[\[dq]b\[dq],0,\[dq]a\[dq],1] +[\[dq]b\[dq],0,\[dq]b\[dq],1] +.EE +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]foreach .[] as $item (0; . + $item)\[aq] \[rs] + <<< \[aq][1,2,3,4,5]\[aq] +1 +3 +6 +10 +15 +.EE +.IP +.EX +$ jq \[aq]foreach .[] as $item (0; . + $item; [$item, . * 2])\[aq] \[rs] + <<< \[aq][1,2,3,4,5]\[aq] +[1,2] +[2,6] +[3,12] +[4,20] +[5,30] +.EE +.IP +.EX +$ jq \[aq]foreach .[] as $item (0; . + 1; {index: ., $item})\[aq] \[rs] + <<< \[aq][\[dq]foo\[dq], \[dq]bar\[dq], \[dq]baz\[dq]]\[aq] +{\[dq]index\[dq]:1,\[dq]item\[dq]:\[dq]foo\[dq]} +{\[dq]index\[dq]:2,\[dq]item\[dq]:\[dq]bar\[dq]} +{\[dq]index\[dq]:3,\[dq]item\[dq]:\[dq]baz\[dq]} +.EE +.SH FUNCTION DEFINITIONS +When you have a filter \f[CR]g\f[R], you can give it a name \f[CR]f\f[R] +as follows: +.IP +.EX +def f: g; +.EE +.PP +This is called a \f[I]function definition\f[R]. +Many builtin functions are implemented by definition. +.TP +\f[I]Example\f[R] +The definition \f[CR]def increment: . + 1;\f[R] gives the filter +\f[CR]. + 1\f[R] the name \f[CR]increment\f[R]. +.PP +A function definition \f[CR]def f: g;\f[R] that is followed by a filter +\f[CR]h\f[R] is a filter in which both \f[CR]g\f[R] and \f[CR]h\f[R] may +call \f[CR]f\f[R]. +(Calls of \f[CR]f\f[R] in \f[CR]g\f[R] are recursive calls.) +.TP +\f[I]Example\f[R] +The filter \f[CR]def increment: . + 1; 2 | increment\f[R] is equivalent +to \f[CR]2 | . + 1\f[R]. +.TP +\f[I]Note\f[R] +In jq, you can write definitions wherever you can write a filter. +That allows definitions in places that might be considered rather +unorthodox in other programming languages. +For example, you can write \f[CR]1 + def a: 2; def b: 3; a * b\f[R], +which is equivalent to \f[CR]1 + 2 * 3\f[R]. +.PP +A function may take arguments, for example: +.IP +.EX +def map(f): [.[] | f]; +.EE +.PP +Arguments are passed as \f[I]filters\f[R] (functions with no arguments), +\f[I]not\f[R] as values. +The same argument may be referenced multiple times with different +inputs; for example, in \f[CR]map\f[R], the argument \f[CR]f\f[R] is run +for each element of the input array. +Arguments to a function work more like callbacks than like value +arguments. +This is important to understand. +.TP +\f[I]Example\f[R] +Consider the following filter: +.IP +.EX +def foo(f): f|f; +5|foo(.*2) +.EE +The result will be 20 because \f[CR]f\f[R] is \f[CR].*2\f[R], and during +the first invocation of \f[CR]f\f[R] \f[CR].\f[R] will be 5, and the +second time it will be 10 (5 * 2), so the result will be 20. +.PP +If you want to pass an argument by value, you can prefix its name with +\f[CR]$\f[R]. +.TP +\f[I]Example\f[R] +The definition +.IP +.EX +def addvalue($f): map(. + $f); +.EE +is equivalent to +.IP +.EX +def addvalue(f): f as $f | map(. + $f);\[ga] +.EE +With either definition, \f[CR]addvalue(.foo)\f[R] adds the current +input\[cq]s \f[CR].foo\f[R] field to each element of the input. +.PP +Multiple definitions using the same function name are allowed. +Each re\-definition replaces the previous one for the same number of +function arguments, but only for references from functions (or main +program) subsequent to the re\-definition. +See also the section on scoping. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]def addvalue(f): . + [f]; map(addvalue(.[0]))\[aq] \[rs] + <<< \[aq][[1,2],[10,20]]\[aq] +[[1,2,1], [10,20,10]] +.EE +.IP +.EX +$ jq \[aq]def addvalue(f): f as $x | map(. + $x); addvalue(.[0])\[aq] \[rs] + <<< \[aq][[1,2],[10,20]]\[aq] +[[1,2,1,2], [10,20,1,2]] +.EE +.SS Recursion +Any jq function can be recursive. +The subsection on recursion functions gives a few examples, such as +\f[CR]recurse\f[R]. +.PP +Tail calls are optimized whenever the expression to the left of the +recursive call outputs its last value. +In practice this means that the expression to the left of the recursive +call should not produce more than one output for each input. +.TP +\f[I]Example\f[R] +The builtin function \f[CR]repeat\f[R] can be naively implemented like +\f[CR]repeat_naive\f[R] below. +It is tail\-recursive, however, it binds \f[CR]f\f[R] to a new argument +whenever \f[CR]repeat_naive\f[R] is called recursively. +This makes \f[CR]f\f[R] more costly to call with every recursion step. +For that reason, \f[CR]repeat\f[R] is implemented like below, where +\f[CR]f\f[R] is bound only once, and the recursive call does not have to +perform any binding. +.IP +.EX +def repeat_naive(f): + f, repeat_naive(f); + +def repeat(f): + def _repeat: + f, _repeat; + _repeat; +.EE +.TP +\f[I]Example\f[R] +The builtin function \f[CR]while\f[R] is also implemented recursively. +We apply a similar transformation as above for \f[CR]repeat\f[R] to keep +the cost of calls to \f[CR]cond\f[R] and \f[CR]update\f[R] constant: +.IP +.EX +def while_naive(cond; update): + if cond + then ., (update | while_naive(cond; update)) + else empty + end; + +def while (cond; update): + def _while: + if cond + then ., (update | _while) + else empty + end; + _while +.EE +.SS Generators and iterators +jq expressions are generators in that they can produce zero, one, or +more values for each input. +For example, \f[CR].[]\f[R] generates all the values in its input (which +must be an array or an object), and \f[CR]range(0; 10)\f[R] generates +the integers 0, 1, \&..., 9. +.PP +Even the comma operator is a generator, generating first the values +generated by the expression to the left of the comma, then the values +generated by the expression on the right of the comma. +.PP +The \f[CR]empty\f[R] builtin is the generator that produces zero +outputs. +The \f[CR]empty\f[R] builtin backtracks to the preceding generator +expression. +.PP +All jq functions can be generators just by using builtin generators. +It is also possible to construct new generators using only recursion and +the comma operator. +If recursive calls are \[lq]in tail position\[rq] then the generator +will be efficient. +In the example below the recursive call by \f[CR]_range\f[R] to itself +is in tail position. +The example shows off three advanced topics: tail recursion, generator +construction, and sub\-functions. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]def range(init; upto; by): def _range: if (by > 0 and . < upto) or (by < 0 and . > upto) then ., ((.+by)|_range) else . end; if by == 0 then init else init|_range end | select((by > 0 and . < upto) or (by < 0 and . > upto)); range(0; 10; 3)\[aq] \[rs] + <<< \[aq]null\[aq] +0 +3 +6 +9 +.EE +.IP +.EX +$ jq \[aq]def while(cond; update): def _while: if cond then ., (update | _while) else empty end; _while; [while(.<100; .*2)]\[aq] \[rs] + <<< \[aq]1\[aq] +[1,2,4,8,16,32,64] +.EE +.SH ASSIGNMENT +jq provides a number of binary assignment operators, such as +\f[CR]|=\f[R] and \f[CR]=\f[R]. +These replace parts of the input at positions given by the left\-hand +side with outputs given by the right\-hand side, then return the updated +input. +.TP +\f[I]Example\f[R] +The filter \f[CR]{a: 1, b: 2} | .a = 3\f[R] outputs +\f[CR]{a: 3, b: 2}\f[R]. +Here, we replaced the value at position \f[CR].a\f[R] with 3. +.PP +All values in jq are immutable. +That means that the input to an assignment is not actually changed; +instead, you can think of an assignment creating a \f[I]copy\f[R] of its +input before changing it, then returning the changed copy. +The original input remains the same. +.TP +\f[I]Example\f[R] +The filter \f[CR]{a:{b:{c:1}}} | (.a.b = 3), .\f[R] outputs +\f[CR]{\[dq]a\[dq]:{\[dq]b\[dq]:3}}\f[R] and +\f[CR]{\[dq]a\[dq]:{\[dq]b\[dq]:{\[dq]c\[dq]:1}}}\f[R], because the last +sub\-expression, \f[CR].\f[R], sees the original value, not the modified +value. +.PP +We can use any kind of compound path that starts with \f[CR].\f[R] on +the left\-hand side of an assignment, such as \f[CR].[].a\f[R] or +\f[CR].[0]\f[R]. +We\[cq]ll discuss usage of other filters on the left\-hand side in +complex assignments. +.SS Update assignment: \f[CR]|=\f[R] +For every value returned by \f[CR]p\f[R], the update operator +\f[CR]p |= f\f[R] replaces that value by the output of \f[CR]f\f[R] +applied to \f[CR]v\f[R]. +.TP +\f[I]Example\f[R] +The filter \f[CR]{foo: 1, bar: 3} | .foo |= .+1\f[R] builds an object +with the \f[CR]foo\f[R] field set to the input\[cq]s \f[CR]foo\f[R] plus +1, resulting in the output \f[CR]{foo: 2, bar: 3}\f[R]. +.TP +\f[I]Example\f[R] +The filter \f[CR][1, 2, 3] | .[] |= . + 1\f[R] returns +\f[CR][2, 3, 4]\f[R]. +Here, \f[CR].[]\f[R] returns multiple positions, and the values at each +of these positions are updated with \f[CR]. + 1\f[R]. +.PP +If the right\-hand side outputs no values (i.e., \f[CR]empty\f[R]), then +the value at the current position is deleted, as with +\f[CR]del(path)\f[R]. +.TP +\f[I]Example\f[R] +The filter \f[CR]{a: 1, b: 2} | .a |= empty\f[R] returns +\f[CR]{b: 2}\f[R]. +.TP +\f[I]Example\f[R] +The filter \f[CR][1, 2, 3] | .[0] |= empty\f[R] returns +\f[CR][2, 3]\f[R]. +.TP +\f[I]Example\f[R] +The filter \f[CR][1, 2, 3, 4] | .[] |= select(. % 2 == 0)\f[R] returns +\f[CR][2, 4]\f[R]. +That means that we can use assignments to filter values from arrays and +objects. +.PP +If the right\-hand side outputs multiple values, only the first output +is used. +.TP +\f[I]Example\f[R] +The filter \f[CR]{a: 1} | .a |= (2, 3)\f[R] yields \f[CR]{a: 2}\f[R]. +.TP +\f[I]Compatibility\f[R] +In jq 1.5 and earlier releases, only the last output was used. +.SS Plain assignment: \f[CR]=\f[R] +The plain assignment operator \f[CR]=\f[R] differs from \f[CR]|=\f[R] in +two main points: First, the input to the right\-hand side is the same as +the input to the left\-hand side, not the current value returned by the +left\-hand side. +Second, when the right\-hand side returns multiple values, then the +operation is performed for each of these values. +.TP +\f[I]Example\f[R] +The filter \f[CR]{a:1} | .b = 2\f[R] yields \f[CR]{a: 1, b: 2}\f[R]. +.TP +\f[I]Example\f[R] +To see the difference between \f[CR]=\f[R] and \f[CR]|=\f[R], let us +provide the input +\f[CR]{\[dq]a\[dq]: {\[dq]b\[dq]: 10}, \[dq]b\[dq]: 20}\f[R] to the +programs \f[CR].a = .b\f[R] and \f[CR].a |= .b\f[R]. +The former sets the \f[CR]a\f[R] field of the input to the \f[CR]b\f[R] +field of the input, producing the output +\f[CR]{\[dq]a\[dq]: 20, \[dq]b\[dq]: 20}\f[R]. +The latter sets the \f[CR]a\f[R] field of the input to the \f[CR]a\f[R] +field\[cq]s \f[CR]b\f[R] field, producing +\f[CR]{\[dq]a\[dq]: 10, \[dq]b\[dq]: 20}\f[R]. +.TP +\f[I]Example\f[R] +The filter \f[CR]{a: 1} | .a = (2, 3)\f[R] yields two outputs, namely +\f[CR]{a: 2}\f[R] and \f[CR]{a: 3}\f[R]. +.TP +\f[I]Note\f[R] +The filter \f[CR]a = b\f[R] is equivalent to +\f[CR]b as $x | a |= $x\f[R] (where \f[CR]$x\f[R] is a fresh variable +name). +.TP +\f[I]Note\f[R] +Assignment works a little differently in jq than in most programming +languages. +jq does not distinguish between references to and copies of something +\[em] two objects or arrays are either equal or not equal, without any +further notion of being \[lq]the same object\[rq] or \[lq]not the same +object\[rq]. +If an object has two fields, \f[CR].foo\f[R] and \f[CR].bar\f[R], and +you set \f[CR].bar = .foo\f[R], then changing \f[CR].foo\f[R] does not +impact \f[CR].bar\f[R]. +If you\[cq]re used to programming in languages like Python, Java, Ruby, +JavaScript, etc., then you can think of it as though jq does a full deep +copy of every object before it does the assignment (for performance it +doesn\[cq]t actually do that, but that\[cq]s the general idea). +This means that it\[cq]s impossible to build circular values in jq (such +as an array whose first element is itself). +This is quite intentional, and ensures that anything a jq program +produces can be represented in JSON. +.PP +Most users will want to use modification assignment operators, such as +\f[CR]|=\f[R] or \f[CR]+=\f[R], rather than \f[CR]=\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].a = .b\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: {\[dq]b\[dq]: 10}, \[dq]b\[dq]: 20}\[aq] +{\[dq]a\[dq]:20,\[dq]b\[dq]:20} +.EE +.IP +.EX +$ jq \[aq].a |= .b\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: {\[dq]b\[dq]: 10}, \[dq]b\[dq]: 20}\[aq] +{\[dq]a\[dq]:10,\[dq]b\[dq]:20} +.EE +.SS Arithmetic update assignment: \f[CR]+=\f[R], \f[CR]\-=\f[R], \f[CR]*=\f[R], \f[CR]/=\f[R], \f[CR]%=\f[R], \f[CR]//=\f[R] +jq has a few operators of the form \f[CR]a op= b\f[R]. +So, \f[CR]+= 1\f[R] can be used to increment values, being the same as +\f[CR]|= . + 1\f[R]. +.PP +Like \f[CR]=\f[R], the right\-hand side of an arithmetic update operator +receives the same input as the left\-hand side, and when the right\-hand +side returns multiple values, then the operation is performed for each +of these values. +.TP +\f[I]Example\f[R] +The filter \f[CR]{a: 1, b: 2} | .a += .b\f[R] yields +\f[CR]{a: 3, b: 2}\f[R], because \f[CR].b\f[R] was executed on the +original input (\f[CR]{a: 1, b: 2}\f[R]), not on the value that it +updated (\f[CR]1\f[R]). +In contrast, \f[CR]{a: 1, b: 2} | .a |= . + .b\f[R] yields an error, +because \f[CR].b\f[R] is executed on the value \f[CR]1\f[R] found at the +position \f[CR].a\f[R]. +.TP +\f[I]Example\f[R] +The filter \f[CR]{a: 1} | .a += (1, 2)\f[R] yields two outputs, namely +\f[CR]{a: 2}\f[R] and \f[CR]{a: 3}\f[R]. +.TP +\f[I]Note\f[R] +For any arithmetic operation \f[CR]op\f[R], the filter +\f[CR]a op= b\f[R] is equivalent to \f[CR]b as $x | a |= . op $x\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].foo += 1\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 42}\[aq] +{\[dq]foo\[dq]: 43} +.EE +.SS Complex assignments +jq accepts far more expressions on the left\-hand side of assignments +than most languages. +So far, we have seen assignments using simple path operators such as +\f[CR].[0]\f[R] and \f[CR].a\f[R] on the left\-hand side. +We are now going to show more complex filters on the left\-hand side. +.PP +First, we can write any compound path on the left\-hand side of an +update. +.TP +\f[I]Example\f[R] +Suppose that the input is an object with a field \[lq]posts\[rq] which +is an array of posts. +The filter \f[CR].posts[0].title = \[dq]JQ Manual\[dq]\f[R] sets the +\[lq]title\[rq] field of the first post. +.TP +\f[I]Example\f[R] +The filter \f[CR].posts[].comments += [\[dq]this is great\[dq]]\f[R] +appends the string \[lq]this is great\[rq] to the \[lq]comments\[rq] +array of \f[I]each\f[R] post in the input. +.PP +In general, on the left\-hand side of an assignment, we can use filters +that evaluate to a \f[I]concatenation of compound paths\f[R], where each +of these compound paths must start with \f[CR].\f[R]. +We call such filters \f[I]path expressions\f[R]. +.PP +When jq evaluates an assignment, it tries to evaluate its left\-hand +side to a concatenation of compound paths. +If it succeeds, it updates the values at the positions corresponding to +these paths. +.TP +\f[I]Example\f[R] +Suppose we want to add a comment to blog posts, using the same +\[lq]blog\[rq] input as above. +This time, we only want to comment on the posts written by +\[lq]stedolan\[rq]. +We can find the comments for these posts using the \[lq]select\[rq] +function described earlier: +.IP +.EX +\&.posts[] | select(.author == \[dq]stedolan\[dq]) | .comments +.EE +We can evaluate this to a concatenation of compound paths \[em] for +example, if the 3rd and 42th post were written by \[lq]stedolan\[rq], +this would yield \f[CR].posts[3].comments, .posts[42].comments\f[R]. +We can therefore use this on the left\-hand side of an assignment, such +as: +.IP +.EX +(.posts[] | select(.author == \[dq]stedolan\[dq]) | .comments) += [\[dq]terrible.\[dq]] +.EE +.TP +\f[I]Example\f[R] +The filter \f[CR]$var.foo = 1\f[R] yields an error, because +\f[CR]$var.foo\f[R] is a compound path that starts with \f[CR]$var\f[R], +not with \f[CR].\f[R]. +Therefore, this path does not point to the input of the assignment. +You can use \f[CR]$var | .foo = 1\f[R] instead. +.TP +\f[I]Example\f[R] +The filter \f[CR]{foo: 1, bar: 2} | (.foo, .bar) |= .+1\f[R] builds an +object with the \f[CR]foo\f[R] field set to the input\[cq]s +\f[CR]foo\f[R] plus 1, and the \f[CR]bar\f[R] field set to the +input\[cq]s \f[CR]bar\f[R] plus 1. +Its output is \f[CR]{foo: 2, bar: 3}\f[R]. +.TP +\f[I]Note\f[R] +Due to precedence rules, \f[CR].a,.b=0\f[R] does not set \f[CR].a\f[R] +and \f[CR].b\f[R], because it is equivalent to \f[CR].a, (.b=0)\f[R]. +The filter \f[CR](.a,.b)=0\f[R] sets both. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq](..|select(type==\[dq]boolean\[dq])) |= if . then 1 else 0 end\[aq] \[rs] + <<< \[aq][true,false,[5,true,[true,[false]],false]]\[aq] +[1,0,[5,1,[1,[0]],0]] +.EE +.IP +.EX +$ jq \[aq](.a, .b) = range(3)\[aq] \[rs] + <<< \[aq]{}\[aq] +{\[dq]a\[dq]:0,\[dq]b\[dq]:0} +{\[dq]a\[dq]:1,\[dq]b\[dq]:1} +{\[dq]a\[dq]:2,\[dq]b\[dq]:2} +.EE +.IP +.EX +$ jq \[aq](.a, .b) |= range(3)\[aq] \[rs] + <<< \[aq]{}\[aq] +{\[dq]a\[dq]:0,\[dq]b\[dq]:0} +.EE +.SS Path expressions +We now show which kinds of filters are path expressions, i.e. +which filters can be used on the left\-hand side of assignments. +.PP +The following filters are path expressions: +.IP \[bu] 2 +\f[CR].\f[R] (identity) +.IP \[bu] 2 +\f[CR]..\f[R] (recursive descent) +.IP \[bu] 2 +compound path: if it starts with some \f[CR]f\f[R], then \f[CR]f\f[R] +must be a path expression +.RS 2 +.IP \[bu] 2 +(\f[CR].[]\f[R] is a path expression because it starts with +\f[CR].\f[R], which is a path expression) +.IP \[bu] 2 +(\f[CR]{}[]\f[R] is \f[I]not\f[R] a path expression, because it starts +with \f[CR]{}\f[R], which is no path expression) +.RE +.IP \[bu] 2 +\f[CR]if i then t else e end\f[R]: if \f[CR]t\f[R] and \f[CR]e\f[R] are +path expressions +.IP \[bu] 2 +\f[CR]f as $x | g\f[R]: if \f[CR]g\f[R] is a path expression +.IP \[bu] 2 +\f[CR]f, g\f[R]: if \f[CR]f\f[R] and \f[CR]g\f[R] are path expressions +.IP \[bu] 2 +\f[CR]f | g\f[R]: if \f[CR]f\f[R] and \f[CR]g\f[R] are path expressions +.IP \[bu] 2 +\f[CR]f // g\f[R]: if \f[CR]f\f[R] and \f[CR]g\f[R] are path expressions +.IP \[bu] 2 +\f[CR]f?\f[R]: if \f[CR]f\f[R] is a path expression +.IP \[bu] 2 +\f[CR]label $x | f\f[R]: if \f[CR]f\f[R] is a path expression +.IP \[bu] 2 +\f[CR]break $x\f[R] +.IP \[bu] 2 +\f[CR]def f: g; h\f[R] (function definition): if \f[CR]h\f[R] is a path +expression +.PP +On the contrary, the following filters output values which do +\f[I]not\f[R] point to a part of their input, therefore they are +\f[I]no\f[R] path expressions: +.IP \[bu] 2 +new values, e.g.\ \f[CR]1\f[R], \[lq]Hello world\[rq], +\f[CR][1, 2]\f[R], \f[CR]{a: 1}\f[R] +.IP \[bu] 2 +arithmetic and comparison operations, e.g.\ \f[CR]. + 1\f[R] +.IP \[bu] 2 +\f[CR]and\f[R], \f[CR]or\f[R] +.IP \[bu] 2 +\f[CR]$x\f[R] (variable) +.IP \[bu] 2 +assignment (\f[CR]|=\f[R], \f[CR]=\f[R], \f[CR]+=\f[R], \&...) +.PP +For function calls, it depends on the function: If the function is +implemented by definition and its definition is a path expression, then +the function call is a path expression as well. +For example, this is the case for select) and recurse. +However, most builtin functions return outputs that do not point to a +part of their input, so calls to them are no path expressions. +.TP +\f[I]Note\f[R] +This characterisation of path expressions is an +\f[I]underapproximation\f[R]; that is, there are filters that do not +correspond to these criteria, yet they can be used on the left\-hand +side of assignments. +For example, our criteria do not say that the filter +\f[CR]if true then empty else 0 end\f[R] is a path expression, because +\f[CR]0\f[R] is not a path expression. +Despite this, we can happily use this filter on the left\-hand side of +an assignment. +Such an assignment will always return its input, because +\f[CR]if true then empty else 0 end\f[R] always evaluates to +\f[CR]empty\f[R], so jq does not attempt to evaluate \f[CR]0\f[R] as +path. +.TP +\f[I]Compatibility\f[R] +jaq\[cq]s approach to handling assignments is quite different from that +of jq and gojq. +Specifically, jaq executes assignments without constructing compound +paths. +This means that jaq does not allow certain filters on the left\-hand +side of assignments, notably \f[CR]f?\f[R] and \f[CR]label $x | f\f[R]. +jaq\[cq]s approach is generally more performant, but in certain +scenarios, jaq and jq will produce different results, in particular when +using \f[CR]f |= empty\f[R]. +However, for the examples in this section, jq and jaq yield the same +outputs. +.SH MANAGING LARGE PROGRAMS +.SS Comments +You can write comments in your jq programs using \f[CR]#\f[R]. +.PP +A \f[CR]#\f[R] character (not part of a string) starts a comment. +All characters from \f[CR]#\f[R] to the end of the line are ignored. +.PP +If the end of the line is preceded by an odd number of backslash +characters, the following line is also considered part of the comment +and is ignored. +.PP +For example, the following code outputs \f[CR][1,3,4,7]\f[R] +.IP +.EX +[ + 1, + # foo \[rs] + 2, + # bar \[rs]\[rs] + 3, + 4, # baz \[rs]\[rs]\[rs] + 5, \[rs] + 6, + 7 + # comment \[rs] + comment \[rs] + comment +] +.EE +.TP +\f[I]Note\f[R] +A backslash continuing the comment on the next line can be useful when +writing the \[lq]shebang\[rq] for a jq script: +.IP +.EX +#!/bin/sh \-\- +# total \- Output the sum of the given arguments (or stdin) +# usage: total [numbers...] +# \[rs] +exec jq \-\-args \-MRnf \-\- \[dq]$0\[dq] \[dq]$\[at]\[dq] + +$ARGS.positional | +reduce ( + if . == [] + then inputs + else .[] + end | + . as $dot | + try tonumber catch false | + if not or isnan then + \[at]json \[dq]total: Invalid number \[rs]($dot).\[rs]n\[dq] | halt_error(1) + end +) as $n (0; . + $n) +.EE +The \f[CR]exec\f[R] line is considered a comment by jq, so it is +ignored. +But it is not ignored by \f[CR]sh\f[R], since in \f[CR]sh\f[R] a +backslash at the end of the line does not continue the comment. +With this trick, when the script is invoked as \f[CR]total 1 2\f[R], +\f[CR]/bin/sh \-\- /path/to/total 1 2\f[R] will be run, and +\f[CR]sh\f[R] will then run +\f[CR]exec jq \-\-args \-MRnf \-\- /path/to/total 1 2\f[R] replacing +itself with a \f[CR]jq\f[R] interpreter invoked with the specified +options (\f[CR]\-M\f[R], \f[CR]\-R\f[R], \f[CR]\-n\f[R], +\f[CR]\-\-args\f[R]), that evaluates the current file (\f[CR]$0\f[R]), +with the arguments (\f[CR]$\[at]\f[R]) that were passed to +\f[CR]sh\f[R]. +.SS Modules +jq has a library/module system. +Modules are files whose names end in \f[CR].jq\f[R]. +.SS Importing / including modules +The directives +.IP +.EX +import RelativePathString as NAME []; +include RelativePathString []; +.EE +.PP +import a module found at the given path relative to a directory in a +search path. +A \f[CR].jq\f[R] suffix will be added to the relative path string. +If \f[CR]import\f[R] is used, the module\[cq]s symbols are prefixed with +\f[CR]NAME::\f[R]. +If \f[CR]include\f[R] is used, the module\[cq]s symbols are imported +into the caller\[cq]s namespace. +.PP +The optional metadata must be a constant jq expression. +It should be an object with keys like \f[CR]homepage\f[R] and so on. +At this time jq only uses the \f[CR]search\f[R] key/value of the +metadata. +The metadata is also made available to users via the +\f[CR]modulemeta\f[R] builtin. +.PP +The \f[CR]search\f[R] key in the metadata, if present, should have a +string or array value (array of strings); this is the search path to be +prefixed to the top\-level search path. +.SS Importing data +The directive +.IP +.EX +import RelativePathString as $NAME []; +.EE +.PP +imports a JSON file found at the given path relative to a directory in a +search path. +A \f[CR].json\f[R] suffix will be added to the relative path string. +The file\[cq]s data will be available as \f[CR]$NAME::NAME\f[R]. +.PP +The optional metadata is considered the same way as module imports. +.SS Providing module metadata +The directive +.IP +.EX +module ; +.EE +.PP +may be put at the beginning of a module file. +It is entirely optional and serves only the purpose of providing +metadata that can be read with the \f[CR]modulemeta\f[R] builtin. +.PP +The metadata must be a constant jq expression. +It should be an object with keys like \f[CR]homepage\f[R]. +At this time jq doesn\[cq]t use this metadata, but it is made available +to users via the \f[CR]modulemeta\f[R] builtin. +.SS Search paths +Modules imported by a program are searched for in a default search path +(see below). +The \f[CR]import\f[R] and \f[CR]include\f[R] directives allow the +importer to alter this path. +.PP +Paths in the search path are subject to various substitutions: +.IP \[bu] 2 +For paths starting with \f[CR]\[ti]/\f[R], the user\[cq]s home directory +is substituted for \f[CR]\[ti]\f[R]. +.IP \[bu] 2 +For paths starting with \f[CR]$ORIGIN/\f[R], the directory where the jq +executable is located is substituted for \f[CR]$ORIGIN\f[R]. +.IP \[bu] 2 +For paths starting with \f[CR]./\f[R] or paths that are \f[CR].\f[R], +the path of the including file is substituted for \f[CR].\f[R]. +For top\-level programs given on the command\-line, the current +directory is used. +.PP +Import directives can optionally specify a search path to which the +default is appended. +.PP +The default search path is the search path given to the \f[CR]\-L\f[R] +command\-line option, else +\f[CR][\[dq]\[ti]/.jq\[dq], \[dq]$ORIGIN/../lib/jq\[dq], \[dq]$ORIGIN/../lib\[dq]]\f[R]. +.PP +Null and empty string path elements terminate search path processing. +.PP +A dependency with relative path \f[CR]foo/bar\f[R] would be searched for +in \f[CR]foo/bar.jq\f[R] and \f[CR]foo/bar/bar.jq\f[R] in the given +search path. +This is intended to allow modules to be placed in a directory along +with, for example, version control files, README files, and so on, but +also to allow for single\-file modules. +.PP +Consecutive components with the same name are not allowed to avoid +ambiguities (e.g., \f[CR]foo/foo\f[R]). +.PP +For example, with \f[CR]\-L$HOME/.jq\f[R] a module \f[CR]foo\f[R] can be +found in \f[CR]$HOME/.jq/foo.jq\f[R] and +\f[CR]$HOME/.jq/foo/foo.jq\f[R]. +.PP +If \f[CR].jq\f[R] exists in the user\[cq]s home directory, and is a file +(not a directory), it is automatically sourced into the main program. +.SH BUILTIN FUNCTIONS +This section documents all functions that are available by default in +any jq program. +.SS Basic functions +.SS \f[CR]empty\f[R] +\f[CR]empty\f[R] returns no results. +None at all. +Not even \f[CR]null\f[R]. +.PP +It\[cq]s useful on occasion. +You\[cq]ll know if you need it :) +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]1, empty, 2\[aq] \[rs] + <<< \[aq]null\[aq] +1 +2 +.EE +.IP +.EX +$ jq \[aq][1,2,empty,3]\[aq] \[rs] + <<< \[aq]null\[aq] +[1,2,3] +.EE +.SS \f[CR]error\f[R], \f[CR]error(message)\f[R] +Produces an error with the input value, or with the message given as the +argument. +Errors can be caught with try/catch. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]try error catch .\[aq] \[rs] + <<< \[aq]\[dq]error message\[dq]\[aq] +\[dq]error message\[dq] +.EE +.IP +.EX +$ jq \[aq]try error(\[dq]invalid value: \[rs](.)\[dq]) catch .\[aq] \[rs] + <<< \[aq]42\[aq] +\[dq]invalid value: 42\[dq] +.EE +.SS \f[CR]length\f[R] +The \f[CR]length\f[R] function gets the length of various different +types of values: +.IP \[bu] 2 +The length of a \f[B]string\f[R] is the number of Unicode codepoints it +contains (which will be the same as its JSON\-encoded length in bytes if +it\[cq]s pure ASCII). +.IP \[bu] 2 +The length of a \f[B]number\f[R] is its absolute value. +.IP \[bu] 2 +The length of an \f[B]array\f[R] is the number of elements. +.IP \[bu] 2 +The length of an \f[B]object\f[R] is the number of key\-value pairs. +.IP \[bu] 2 +The length of \f[B]null\f[R] is zero. +.IP \[bu] 2 +It is an error to use \f[CR]length\f[R] on a \f[B]boolean\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[] | length\[aq] \[rs] + <<< \[aq][[1,2], \[dq]string\[dq], {\[dq]a\[dq]:2}, null, \-5]\[aq] +2 +6 +1 +0 +5 +.EE +.SS \f[CR]keys\f[R], \f[CR]keys_unsorted\f[R] +The builtin function \f[CR]keys\f[R], when given an object, returns its +keys in an array. +.PP +The keys are sorted \[lq]alphabetically\[rq], by unicode codepoint +order. +This is not an order that makes particular sense in any particular +language, but you can count on it being the same for any two objects +with the same set of keys, regardless of locale settings. +.PP +When \f[CR]keys\f[R] is given an array, it returns the valid indices for +that array: the integers from 0 to length\-1. +.PP +The \f[CR]keys_unsorted\f[R] function is just like \f[CR]keys\f[R], but +if the input is an object then the keys will not be sorted, instead the +keys will roughly be in insertion order. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]keys\[aq] \[rs] + <<< \[aq]{\[dq]abc\[dq]: 1, \[dq]abcd\[dq]: 2, \[dq]Foo\[dq]: 3}\[aq] +[\[dq]Foo\[dq], \[dq]abc\[dq], \[dq]abcd\[dq]] +.EE +.IP +.EX +$ jq \[aq]keys\[aq] \[rs] + <<< \[aq][42,3,35]\[aq] +[0,1,2] +.EE +.SS \f[CR]map(f)\f[R], \f[CR]map_values(f)\f[R] +For any filter \f[CR]f\f[R], \f[CR]map(f)\f[R] and +\f[CR]map_values(f)\f[R] apply \f[CR]f\f[R] to each of the values in the +input array or object, that is, to the values of \f[CR].[]\f[R]. +.PP +In the absence of errors, \f[CR]map(f)\f[R] always outputs an array +whereas \f[CR]map_values(f)\f[R] outputs an array if given an array, or +an object if given an object. +.PP +When the input to \f[CR]map_values(f)\f[R] is an object, the output +object has the same keys as the input object except for those keys whose +values when piped to \f[CR]f\f[R] produce no values at all. +.PP +The key difference between \f[CR]map(f)\f[R] and +\f[CR]map_values(f)\f[R] is that the former simply forms an array from +all the values of \f[CR]($x|f)\f[R] for each value, \f[CR]$x\f[R], in +the input array or object, but \f[CR]map_values(f)\f[R] only uses +\f[CR]first($x|f)\f[R]. +.PP +Specifically, for object inputs, \f[CR]map_values(f)\f[R] constructs the +output object by examining in turn the value of +\f[CR]first(.[$k]|f)\f[R] for each key, \f[CR]$k\f[R], of the input. +If this expression produces no values, then the corresponding key will +be dropped; otherwise, the output object will have that value at the +key, \f[CR]$k\f[R]. +.PP +Here are some examples to clarify the behavior of \f[CR]map\f[R] and +\f[CR]map_values\f[R] when applied to arrays. +These examples assume the input is \f[CR][1]\f[R] in all cases: +.IP +.EX +map(.+1) #=> [2] +map(., .) #=> [1,1] +map(empty) #=> [] + +map_values(.+1) #=> [2] +map_values(., .) #=> [1] +map_values(empty) #=> [] +.EE +.PP +\f[CR]map(f)\f[R] is equivalent to \f[CR][.[] | f]\f[R] and +\f[CR]map_values(f)\f[R] is equivalent to \f[CR].[] |= f\f[R]. +.PP +In fact, these are their implementations. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]map(.+1)\[aq] \[rs] + <<< \[aq][1,2,3]\[aq] +[2,3,4] +.EE +.IP +.EX +$ jq \[aq]map_values(.+1)\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2, \[dq]c\[dq]: 3}\[aq] +{\[dq]a\[dq]: 2, \[dq]b\[dq]: 3, \[dq]c\[dq]: 4} +.EE +.IP +.EX +$ jq \[aq]map(., .)\[aq] \[rs] + <<< \[aq][1,2]\[aq] +[1,1,2,2] +.EE +.IP +.EX +$ jq \[aq]map_values(. // empty)\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: null, \[dq]b\[dq]: true, \[dq]c\[dq]: false}\[aq] +{\[dq]b\[dq]:true} +.EE +.SS \f[CR]to_entries\f[R], \f[CR]from_entries\f[R], \f[CR]with_entries(f)\f[R] +These functions convert between an object and an array of key\-value +pairs. +If \f[CR]to_entries\f[R] is passed an object, then for each +\f[CR]k: v\f[R] entry in the input, the output array includes +\f[CR]{\[dq]key\[dq]: k, \[dq]value\[dq]: v}\f[R]. +.PP +\f[CR]from_entries\f[R] does the opposite conversion, and +\f[CR]with_entries(f)\f[R] is a shorthand for +\f[CR]to_entries | map(f) | from_entries\f[R], useful for doing some +operation to all keys and values of an object. +\f[CR]from_entries\f[R] accepts \f[CR]\[dq]key\[dq]\f[R], +\f[CR]\[dq]Key\[dq]\f[R], \f[CR]\[dq]name\[dq]\f[R], +\f[CR]\[dq]Name\[dq]\f[R], \f[CR]\[dq]value\[dq]\f[R], and +\f[CR]\[dq]Value\[dq]\f[R] as keys. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]to_entries\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2}\[aq] +[{\[dq]key\[dq]:\[dq]a\[dq], \[dq]value\[dq]:1}, {\[dq]key\[dq]:\[dq]b\[dq], \[dq]value\[dq]:2}] +.EE +.IP +.EX +$ jq \[aq]from_entries\[aq] \[rs] + <<< \[aq][{\[dq]key\[dq]:\[dq]a\[dq], \[dq]value\[dq]:1}, {\[dq]key\[dq]:\[dq]b\[dq], \[dq]value\[dq]:2}]\[aq] +{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2} +.EE +.IP +.EX +$ jq \[aq]with_entries(.key |= \[dq]KEY_\[dq] + .)\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: 1, \[dq]b\[dq]: 2}\[aq] +{\[dq]KEY_a\[dq]: 1, \[dq]KEY_b\[dq]: 2} +.EE +.SS \f[CR]not\f[R] +The function \f[CR]not\f[R] negates the boolean value of its input. +It is defined as: +.IP +.EX +def not: if . then false else true; +.EE +.SS \f[CR]select(boolean_expression)\f[R] +The function \f[CR]select(f)\f[R] produces its input unchanged if +\f[CR]f\f[R] returns true for that input, and produces no output +otherwise. +.PP +It\[cq]s useful for filtering lists: +\f[CR][1,2,3] | map(select(. >= 2))\f[R] will give you \f[CR][2,3]\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]map(select(. >= 2))\[aq] \[rs] + <<< \[aq][1,5,3,0,7]\[aq] +[5,3,7] +.EE +.IP +.EX +$ jq \[aq].[] | select(.id == \[dq]second\[dq])\[aq] \[rs] + <<< \[aq][{\[dq]id\[dq]: \[dq]first\[dq], \[dq]val\[dq]: 1}, {\[dq]id\[dq]: \[dq]second\[dq], \[dq]val\[dq]: 2}]\[aq] +{\[dq]id\[dq]: \[dq]second\[dq], \[dq]val\[dq]: 2} +.EE +.SS \f[CR]type\f[R] +The \f[CR]type\f[R] function returns the type of its argument as a +string, which is one of null, boolean, number, string, array or object. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]map(type)\[aq] \[rs] + <<< \[aq][0, false, [], {}, null, \[dq]hello\[dq]]\[aq] +[\[dq]number\[dq], \[dq]boolean\[dq], \[dq]array\[dq], \[dq]object\[dq], \[dq]null\[dq], \[dq]string\[dq]] +.EE +.SS \f[CR]arrays\f[R], \f[CR]objects\f[R], \f[CR]iterables\f[R], \f[CR]booleans\f[R], \f[CR]numbers\f[R], \f[CR]normals\f[R], \f[CR]finites\f[R], \f[CR]strings\f[R], \f[CR]nulls\f[R], \f[CR]values\f[R], \f[CR]scalars\f[R] +These built\-ins select only inputs that are arrays, objects, iterables +(arrays or objects), booleans, numbers, normal numbers, finite numbers, +strings, null, non\-null values, and non\-iterables, respectively. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[]|numbers\[aq] \[rs] + <<< \[aq][[],{},1,\[dq]foo\[dq],null,true,false]\[aq] +1 +.EE +.SS Membership functions +.SS \f[CR]contains(element)\f[R] +The filter \f[CR]contains(b)\f[R] will produce true if b is completely +contained within the input. +A string B is contained in a string A if B is a substring of A. An array +B is contained in an array A if all elements in B are contained in any +element in A. An object B is contained in object A if all of the values +in B are contained in the value in A with the same key. +All other types are assumed to be contained in each other if they are +equal. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]contains(\[dq]bar\[dq])\[aq] \[rs] + <<< \[aq]\[dq]foobar\[dq]\[aq] +true +.EE +.IP +.EX +$ jq \[aq]contains([\[dq]baz\[dq], \[dq]bar\[dq]])\[aq] \[rs] + <<< \[aq][\[dq]foobar\[dq], \[dq]foobaz\[dq], \[dq]blarp\[dq]]\[aq] +true +.EE +.IP +.EX +$ jq \[aq]contains([\[dq]bazzzzz\[dq], \[dq]bar\[dq]])\[aq] \[rs] + <<< \[aq][\[dq]foobar\[dq], \[dq]foobaz\[dq], \[dq]blarp\[dq]]\[aq] +false +.EE +.IP +.EX +$ jq \[aq]contains({foo: 12, bar: [{barp: 12}]})\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 12, \[dq]bar\[dq]:[1,2,{\[dq]barp\[dq]:12, \[dq]blip\[dq]:13}]}\[aq] +true +.EE +.IP +.EX +$ jq \[aq]contains({foo: 12, bar: [{barp: 15}]})\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 12, \[dq]bar\[dq]:[1,2,{\[dq]barp\[dq]:12, \[dq]blip\[dq]:13}]}\[aq] +false +.EE +.SS \f[CR]indices(s)\f[R] +Outputs an array containing the indices in \f[CR].\f[R] where +\f[CR]s\f[R] occurs. +The input may be an array, in which case if \f[CR]s\f[R] is an array +then the indices output will be those where all elements in \f[CR].\f[R] +match those of \f[CR]s\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]indices(\[dq], \[dq])\[aq] \[rs] + <<< \[aq]\[dq]a,b, cd, efg, hijk\[dq]\[aq] +[3,7,12] +.EE +.IP +.EX +$ jq \[aq]indices(1)\[aq] \[rs] + <<< \[aq][0,1,2,1,3,1,4]\[aq] +[1,3,5] +.EE +.IP +.EX +$ jq \[aq]indices([1,2])\[aq] \[rs] + <<< \[aq][0,1,2,3,1,4,2,5,1,2,6,7]\[aq] +[1,8] +.EE +.SS \f[CR]index(s)\f[R], \f[CR]rindex(s)\f[R] +Outputs the index of the first (\f[CR]index\f[R]) or last +(\f[CR]rindex\f[R]) occurrence of \f[CR]s\f[R] in the input. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]index(\[dq], \[dq])\[aq] \[rs] + <<< \[aq]\[dq]a,b, cd, efg, hijk\[dq]\[aq] +3 +.EE +.IP +.EX +$ jq \[aq]index(1)\[aq] \[rs] + <<< \[aq][0,1,2,1,3,1,4]\[aq] +1 +.EE +.IP +.EX +$ jq \[aq]index([1,2])\[aq] \[rs] + <<< \[aq][0,1,2,3,1,4,2,5,1,2,6,7]\[aq] +1 +.EE +.IP +.EX +$ jq \[aq]rindex(\[dq], \[dq])\[aq] \[rs] + <<< \[aq]\[dq]a,b, cd, efg, hijk\[dq]\[aq] +12 +.EE +.IP +.EX +$ jq \[aq]rindex(1)\[aq] \[rs] + <<< \[aq][0,1,2,1,3,1,4]\[aq] +5 +.EE +.IP +.EX +$ jq \[aq]rindex([1,2])\[aq] \[rs] + <<< \[aq][0,1,2,3,1,4,2,5,1,2,6,7]\[aq] +8 +.EE +.SS \f[CR]inside\f[R] +The filter \f[CR]inside(b)\f[R] will produce true if the input is +completely contained within b. +It is, essentially, an inversed version of \f[CR]contains\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]inside(\[dq]foobar\[dq])\[aq] \[rs] + <<< \[aq]\[dq]bar\[dq]\[aq] +true +.EE +.IP +.EX +$ jq \[aq]inside([\[dq]foobar\[dq], \[dq]foobaz\[dq], \[dq]blarp\[dq]])\[aq] \[rs] + <<< \[aq][\[dq]baz\[dq], \[dq]bar\[dq]]\[aq] +true +.EE +.IP +.EX +$ jq \[aq]inside([\[dq]foobar\[dq], \[dq]foobaz\[dq], \[dq]blarp\[dq]])\[aq] \[rs] + <<< \[aq][\[dq]bazzzzz\[dq], \[dq]bar\[dq]]\[aq] +false +.EE +.IP +.EX +$ jq \[aq]inside({\[dq]foo\[dq]: 12, \[dq]bar\[dq]:[1,2,{\[dq]barp\[dq]:12, \[dq]blip\[dq]:13}]})\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 12, \[dq]bar\[dq]: [{\[dq]barp\[dq]: 12}]}\[aq] +true +.EE +.IP +.EX +$ jq \[aq]inside({\[dq]foo\[dq]: 12, \[dq]bar\[dq]:[1,2,{\[dq]barp\[dq]:12, \[dq]blip\[dq]:13}]})\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 12, \[dq]bar\[dq]: [{\[dq]barp\[dq]: 15}]}\[aq] +false +.EE +.SS \f[CR]has(key)\f[R] +The builtin function \f[CR]has\f[R] returns whether the input object has +the given key, or the input array has an element at the given index. +.PP +\f[CR]has($key)\f[R] has the same effect as checking whether +\f[CR]$key\f[R] is a member of the array returned by \f[CR]keys\f[R], +although \f[CR]has\f[R] will be faster. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]map(has(\[dq]foo\[dq]))\[aq] \[rs] + <<< \[aq][{\[dq]foo\[dq]: 42}, {}]\[aq] +[true, false] +.EE +.IP +.EX +$ jq \[aq]map(has(2))\[aq] \[rs] + <<< \[aq][[0,1], [\[dq]a\[dq],\[dq]b\[dq],\[dq]c\[dq]]]\[aq] +[false, true] +.EE +.SS \f[CR]in\f[R] +The builtin function \f[CR]in\f[R] returns whether or not the input key +is in the given object, or the input index corresponds to an element in +the given array. +It is, essentially, an inversed version of \f[CR]has\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[] | in({\[dq]foo\[dq]: 42})\[aq] \[rs] + <<< \[aq][\[dq]foo\[dq], \[dq]bar\[dq]]\[aq] +true +false +.EE +.IP +.EX +$ jq \[aq]map(in([0,1]))\[aq] \[rs] + <<< \[aq][2, 0]\[aq] +[false, true] +.EE +.SS \f[CR]bsearch(x)\f[R] +\f[CR]bsearch(x)\f[R] conducts a binary search for x in the input array. +If the input is sorted and contains x, then \f[CR]bsearch(x)\f[R] will +return its index in the array; otherwise, if the array is sorted, it +will return (\-1 \- ix) where ix is an insertion point such that the +array would still be sorted after the insertion of x at ix. +If the array is not sorted, \f[CR]bsearch(x)\f[R] will return an integer +that is probably of no interest. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]bsearch(0)\[aq] \[rs] + <<< \[aq][0,1]\[aq] +0 +.EE +.IP +.EX +$ jq \[aq]bsearch(0)\[aq] \[rs] + <<< \[aq][1,2,3]\[aq] +\-1 +.EE +.IP +.EX +$ jq \[aq]bsearch(4) as $ix | if $ix < 0 then .[\-(1+$ix)] = 4 else . end\[aq] \[rs] + <<< \[aq][1,2,3]\[aq] +[1,2,3,4] +.EE +.SS Path expression functions +The following functions all take a path expression. +.SS \f[CR]path(path_expression)\f[R] +Outputs array representations of the given path expression in +\f[CR].\f[R]. +The outputs are arrays of strings (object keys) and/or numbers (array +indices). +The outputs of this function can be processed with path functions. +.PP +Path expressions are jq expressions like \f[CR].a\f[R], but also +\f[CR].[]\f[R]. +There are two types of path expressions: ones that can match exactly, +and ones that cannot. +For example, \f[CR].a.b.c\f[R] is an exact match path expression, while +\f[CR].a[].b\f[R] is not. +.PP +\f[CR]path(exact_path_expression)\f[R] will produce the array +representation of the path expression even if it does not exist in +\f[CR].\f[R], if \f[CR].\f[R] is \f[CR]null\f[R] or an array or an +object. +.PP +\f[CR]path(pattern)\f[R] will produce array representations of the paths +matching \f[CR]pattern\f[R] if the paths exist in \f[CR].\f[R]. +.PP +Note that the path expressions are not different from normal +expressions. +The expression \f[CR]path(..|select(type==\[dq]boolean\[dq]))\f[R] +outputs all the paths to boolean values in \f[CR].\f[R], and only those +paths. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]path(.a[0].b)\[aq] \[rs] + <<< \[aq]null\[aq] +[\[dq]a\[dq],0,\[dq]b\[dq]] +.EE +.IP +.EX +$ jq \[aq][path(..)]\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]:[{\[dq]b\[dq]:1}]}\[aq] +[[],[\[dq]a\[dq]],[\[dq]a\[dq],0],[\[dq]a\[dq],0,\[dq]b\[dq]]] +.EE +.SS \f[CR]del(path_expression)\f[R] +The builtin function \f[CR]del\f[R] removes a key and its corresponding +value from an object. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]del(.foo)\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]: 42, \[dq]bar\[dq]: 9001, \[dq]baz\[dq]: 42}\[aq] +{\[dq]bar\[dq]: 9001, \[dq]baz\[dq]: 42} +.EE +.IP +.EX +$ jq \[aq]del(.[1, 2])\[aq] \[rs] + <<< \[aq][\[dq]foo\[dq], \[dq]bar\[dq], \[dq]baz\[dq]]\[aq] +[\[dq]foo\[dq]] +.EE +.SS \f[CR]pick(pathexps)\f[R] +Emit the projection of the input object or array defined by the +specified sequence of path expressions, such that if \f[CR]p\f[R] is any +one of these specifications, then \f[CR](. | p)\f[R] will evaluate to +the same value as \f[CR](. | pick(pathexps) | p)\f[R]. +For arrays, negative indices and \f[CR].[m:n]\f[R] specifications should +not be used. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]pick(.a, .b.c, .x)\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]: 1, \[dq]b\[dq]: {\[dq]c\[dq]: 2, \[dq]d\[dq]: 3}, \[dq]e\[dq]: 4}\[aq] +{\[dq]a\[dq]:1,\[dq]b\[dq]:{\[dq]c\[dq]:2},\[dq]x\[dq]:null} +.EE +.IP +.EX +$ jq \[aq]pick(.[2], .[0], .[0])\[aq] \[rs] + <<< \[aq][1,2,3,4]\[aq] +[1,null,3] +.EE +.SS Path functions +The following functions all produce or process paths in the format +output by the \f[CR]path\f[R] function. +.SS \f[CR]paths\f[R], \f[CR]paths(node_filter)\f[R] +\f[CR]paths\f[R] outputs the paths to all the elements in its input +(except it does not output the empty list, representing . +itself). +.PP +\f[CR]paths(f)\f[R] outputs the paths to any values for which +\f[CR]f\f[R] is \f[CR]true\f[R]. +That is, \f[CR]paths(type == \[dq]number\[dq])\f[R] outputs the paths to +all numeric values. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][paths]\[aq] \[rs] + <<< \[aq][1,[[],{\[dq]a\[dq]:2}]]\[aq] +[[0],[1],[1,0],[1,1],[1,1,\[dq]a\[dq]]] +.EE +.IP +.EX +$ jq \[aq][paths(type == \[dq]number\[dq])]\[aq] \[rs] + <<< \[aq][1,[[],{\[dq]a\[dq]:2}]]\[aq] +[[0],[1,1,\[dq]a\[dq]]] +.EE +.SS \f[CR]getpath(PATHS)\f[R] +The builtin function \f[CR]getpath\f[R] outputs the values in +\f[CR].\f[R] found at each path in \f[CR]PATHS\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]getpath([\[dq]a\[dq],\[dq]b\[dq]])\[aq] \[rs] + <<< \[aq]null\[aq] +null +.EE +.IP +.EX +$ jq \[aq][getpath([\[dq]a\[dq],\[dq]b\[dq]], [\[dq]a\[dq],\[dq]c\[dq]])]\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]:{\[dq]b\[dq]:0, \[dq]c\[dq]:1}}\[aq] +[0, 1] +.EE +.SS \f[CR]setpath(PATHS; VALUE)\f[R] +The builtin function \f[CR]setpath\f[R] sets the \f[CR]PATHS\f[R] in +\f[CR].\f[R] to \f[CR]VALUE\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]setpath([\[dq]a\[dq],\[dq]b\[dq]]; 1)\[aq] \[rs] + <<< \[aq]null\[aq] +{\[dq]a\[dq]: {\[dq]b\[dq]: 1}} +.EE +.IP +.EX +$ jq \[aq]setpath([\[dq]a\[dq],\[dq]b\[dq]]; 1)\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]:{\[dq]b\[dq]:0}}\[aq] +{\[dq]a\[dq]: {\[dq]b\[dq]: 1}} +.EE +.IP +.EX +$ jq \[aq]setpath([0,\[dq]a\[dq]]; 1)\[aq] \[rs] + <<< \[aq]null\[aq] +[{\[dq]a\[dq]:1}] +.EE +.SS \f[CR]delpaths(PATHS)\f[R] +The builtin function \f[CR]delpaths\f[R] deletes the \f[CR]PATHS\f[R] in +\f[CR].\f[R]. +\f[CR]PATHS\f[R] must be an array of paths, where each path is an array +of strings and numbers. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]delpaths([[\[dq]a\[dq],\[dq]b\[dq]]])\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]:{\[dq]b\[dq]:1},\[dq]x\[dq]:{\[dq]y\[dq]:2}}\[aq] +{\[dq]a\[dq]:{},\[dq]x\[dq]:{\[dq]y\[dq]:2}} +.EE +.SS Reduction functions +.SS \f[CR]add\f[R], \f[CR]add(generator)\f[R] +The filter \f[CR]add\f[R] takes as input an array, and produces as +output the elements of the array added together. +This might mean summed, concatenated or merged depending on the types of +the elements of the input array \- the rules are the same as those for +the \f[CR]+\f[R] operator (described above). +.PP +If the input is an empty array, \f[CR]add\f[R] returns \f[CR]null\f[R]. +.PP +\f[CR]add(generator)\f[R] operates on the given generator rather than +the input. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]add\[aq] \[rs] + <<< \[aq][\[dq]a\[dq],\[dq]b\[dq],\[dq]c\[dq]]\[aq] +\[dq]abc\[dq] +.EE +.IP +.EX +$ jq \[aq]add\[aq] \[rs] + <<< \[aq][1, 2, 3]\[aq] +6 +.EE +.IP +.EX +$ jq \[aq]add\[aq] \[rs] + <<< \[aq][]\[aq] +null +.EE +.IP +.EX +$ jq \[aq]add(.[].a)\[aq] \[rs] + <<< \[aq][{\[dq]a\[dq]:3}, {\[dq]a\[dq]:5}, {\[dq]b\[dq]:6}]\[aq] +8 +.EE +.SS \f[CR]any\f[R], \f[CR]any(condition)\f[R], \f[CR]any(generator; condition)\f[R] +The filter \f[CR]any\f[R] takes as input an array of boolean values, and +produces \f[CR]true\f[R] as output if any of the elements of the array +are \f[CR]true\f[R]. +.PP +If the input is an empty array, \f[CR]any\f[R] returns \f[CR]false\f[R]. +.PP +The \f[CR]any(condition)\f[R] form applies the given condition to the +elements of the input array. +.PP +The \f[CR]any(generator; condition)\f[R] form applies the given +condition to all the outputs of the given generator. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]any\[aq] \[rs] + <<< \[aq][true, false]\[aq] +true +.EE +.IP +.EX +$ jq \[aq]any\[aq] \[rs] + <<< \[aq][false, false]\[aq] +false +.EE +.IP +.EX +$ jq \[aq]any\[aq] \[rs] + <<< \[aq][]\[aq] +false +.EE +.SS \f[CR]all\f[R], \f[CR]all(condition)\f[R], \f[CR]all(generator; condition)\f[R] +The filter \f[CR]all\f[R] takes as input an array of boolean values, and +produces \f[CR]true\f[R] as output if all of the elements of the array +are \f[CR]true\f[R]. +.PP +The \f[CR]all(condition)\f[R] form applies the given condition to the +elements of the input array. +.PP +The \f[CR]all(generator; condition)\f[R] form applies the given +condition to all the outputs of the given generator. +.PP +If the input is an empty array, \f[CR]all\f[R] returns \f[CR]true\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]all\[aq] \[rs] + <<< \[aq][true, false]\[aq] +false +.EE +.IP +.EX +$ jq \[aq]all\[aq] \[rs] + <<< \[aq][true, true]\[aq] +true +.EE +.IP +.EX +$ jq \[aq]all\[aq] \[rs] + <<< \[aq][]\[aq] +true +.EE +.SS Number functions +jq currently only has IEEE754 double\-precision (64\-bit) floating point +number support. +.PP +Besides simple arithmetic operators such as \f[CR]+\f[R], jq also has +most standard math functions from the C math library. +C math functions that take a single input argument (e.g., +\f[CR]sin()\f[R]) are available as zero\-argument jq functions. +C math functions that take two input arguments (e.g., \f[CR]pow()\f[R]) +are available as two\-argument jq functions that ignore \f[CR].\f[R]. +C math functions that take three input arguments are available as +three\-argument jq functions that ignore \f[CR].\f[R]. +.PP +Availability of standard math functions depends on the availability of +the corresponding math functions in your operating system and C math +library. +Unavailable math functions will be defined but will raise an error. +.PP +One\-input C math functions: \f[CR]acos\f[R] \f[CR]acosh\f[R] +\f[CR]asin\f[R] \f[CR]asinh\f[R] \f[CR]atan\f[R] \f[CR]atanh\f[R] +\f[CR]cbrt\f[R] \f[CR]ceil\f[R] \f[CR]cos\f[R] \f[CR]cosh\f[R] +\f[CR]erf\f[R] \f[CR]erfc\f[R] \f[CR]exp\f[R] \f[CR]exp10\f[R] +\f[CR]exp2\f[R] \f[CR]expm1\f[R] \f[CR]fabs\f[R] \f[CR]floor\f[R] +\f[CR]gamma\f[R] \f[CR]j0\f[R] \f[CR]j1\f[R] \f[CR]lgamma\f[R] +\f[CR]log\f[R] \f[CR]log10\f[R] \f[CR]log1p\f[R] \f[CR]log2\f[R] +\f[CR]logb\f[R] \f[CR]nearbyint\f[R] \f[CR]rint\f[R] \f[CR]round\f[R] +\f[CR]significand\f[R] \f[CR]sin\f[R] \f[CR]sinh\f[R] \f[CR]sqrt\f[R] +\f[CR]tan\f[R] \f[CR]tanh\f[R] \f[CR]tgamma\f[R] \f[CR]trunc\f[R] +\f[CR]y0\f[R] \f[CR]y1\f[R]. +.PP +Two\-input C math functions: \f[CR]atan2\f[R] \f[CR]copysign\f[R] +\f[CR]drem\f[R] \f[CR]fdim\f[R] \f[CR]fmax\f[R] \f[CR]fmin\f[R] +\f[CR]fmod\f[R] \f[CR]frexp\f[R] \f[CR]hypot\f[R] \f[CR]jn\f[R] +\f[CR]ldexp\f[R] \f[CR]modf\f[R] \f[CR]nextafter\f[R] +\f[CR]nexttoward\f[R] \f[CR]pow\f[R] \f[CR]remainder\f[R] +\f[CR]scalb\f[R] \f[CR]scalbln\f[R] \f[CR]yn\f[R]. +.PP +Three\-input C math functions: \f[CR]fma\f[R]. +.PP +See your system\[cq]s manual for more information on each of these. +.SS \f[CR]abs\f[R] +The builtin function \f[CR]abs\f[R] is defined naively as: +\f[CR]if . < 0 then \- . else . end\f[R]. +.PP +For numeric input, this is the absolute value. +See the section on the identity filter for the implications of this +definition for numeric input. +.PP +To compute the absolute value of a number as a floating point number, +you may wish use \f[CR]fabs\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]map(abs)\[aq] \[rs] + <<< \[aq][\-10, \-1.1, \-1e\-1]\[aq] +[10,1.1,1e\-1] +.EE +.SS \f[CR]floor\f[R] +The \f[CR]floor\f[R] function returns the floor of its numeric input. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]floor\[aq] \[rs] + <<< \[aq]3.14159\[aq] +3 +.EE +.SS \f[CR]sqrt\f[R] +The \f[CR]sqrt\f[R] function returns the square root of its numeric +input. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]sqrt\[aq] \[rs] + <<< \[aq]9\[aq] +3 +.EE +.SS \f[CR]infinite\f[R], \f[CR]nan\f[R], \f[CR]isinfinite\f[R], \f[CR]isnan\f[R], \f[CR]isfinite\f[R], \f[CR]isnormal\f[R] +Some arithmetic operations can yield infinities and \[lq]not a +number\[rq] (NaN) values. +The \f[CR]isinfinite\f[R] builtin returns \f[CR]true\f[R] if its input +is infinite. +The \f[CR]isnan\f[R] builtin returns \f[CR]true\f[R] if its input is a +NaN. +The \f[CR]infinite\f[R] builtin returns a positive infinite value. +The \f[CR]nan\f[R] builtin returns a NaN. +The \f[CR]isnormal\f[R] builtin returns true if its input is a normal +number. +.PP +Note that division by zero raises an error. +.PP +Currently most arithmetic operations operating on infinities, NaNs, and +sub\-normals do not raise errors. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[] | (infinite * .) < 0\[aq] \[rs] + <<< \[aq][\-1, 1]\[aq] +true +false +.EE +.IP +.EX +$ jq \[aq]infinite, nan | type\[aq] \[rs] + <<< \[aq]null\[aq] +\[dq]number\[dq] +\[dq]number\[dq] +.EE +.SS Array functions +.SS \f[CR]sort\f[R], \f[CR]sort_by(path_expression)\f[R] +The \f[CR]sort\f[R] functions sorts its input, which must be an array. +Values are sorted using the order given by \f[CR]<\f[R]. +.PP +\f[CR]sort_by\f[R] may be used to sort by a particular field of an +object, or by applying any jq filter. +\f[CR]sort_by(f)\f[R] compares two elements by comparing the result of +\f[CR]f\f[R] on each element. +When \f[CR]f\f[R] produces multiple values, it firstly compares the +first values, and the second values if the first values are equal, and +so on. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]sort\[aq] \[rs] + <<< \[aq][8,3,null,6]\[aq] +[null,3,6,8] +.EE +.IP +.EX +$ jq \[aq]sort_by(.foo)\[aq] \[rs] + <<< \[aq][{\[dq]foo\[dq]:4, \[dq]bar\[dq]:10}, {\[dq]foo\[dq]:3, \[dq]bar\[dq]:10}, {\[dq]foo\[dq]:2, \[dq]bar\[dq]:1}]\[aq] +[{\[dq]foo\[dq]:2, \[dq]bar\[dq]:1}, {\[dq]foo\[dq]:3, \[dq]bar\[dq]:10}, {\[dq]foo\[dq]:4, \[dq]bar\[dq]:10}] +.EE +.IP +.EX +$ jq \[aq]sort_by(.foo, .bar)\[aq] \[rs] + <<< \[aq][{\[dq]foo\[dq]:4, \[dq]bar\[dq]:10}, {\[dq]foo\[dq]:3, \[dq]bar\[dq]:20}, {\[dq]foo\[dq]:2, \[dq]bar\[dq]:1}, {\[dq]foo\[dq]:3, \[dq]bar\[dq]:10}]\[aq] +[{\[dq]foo\[dq]:2, \[dq]bar\[dq]:1}, {\[dq]foo\[dq]:3, \[dq]bar\[dq]:10}, {\[dq]foo\[dq]:3, \[dq]bar\[dq]:20}, {\[dq]foo\[dq]:4, \[dq]bar\[dq]:10}] +.EE +.SS \f[CR]group_by(path_expression)\f[R] +\f[CR]group_by(.foo)\f[R] takes as input an array, groups the elements +having the same \f[CR].foo\f[R] field into separate arrays, and produces +all of these arrays as elements of a larger array, sorted by the value +of the \f[CR].foo\f[R] field. +.PP +Any jq expression, not just a field access, may be used in place of +\f[CR].foo\f[R]. +The sorting order is the same as described in the \f[CR]sort\f[R] +function above. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]group_by(.foo)\[aq] \[rs] + <<< \[aq][{\[dq]foo\[dq]:1, \[dq]bar\[dq]:10}, {\[dq]foo\[dq]:3, \[dq]bar\[dq]:100}, {\[dq]foo\[dq]:1, \[dq]bar\[dq]:1}]\[aq] +[[{\[dq]foo\[dq]:1, \[dq]bar\[dq]:10}, {\[dq]foo\[dq]:1, \[dq]bar\[dq]:1}], [{\[dq]foo\[dq]:3, \[dq]bar\[dq]:100}]] +.EE +.SS \f[CR]min\f[R], \f[CR]max\f[R], \f[CR]min_by(path_exp)\f[R], \f[CR]max_by(path_exp)\f[R] +Find the minimum or maximum element of the input array. +.PP +The \f[CR]min_by(path_exp)\f[R] and \f[CR]max_by(path_exp)\f[R] +functions allow you to specify a particular field or property to +examine, e.g. +\f[CR]min_by(.foo)\f[R] finds the object with the smallest +\f[CR]foo\f[R] field. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]min\[aq] \[rs] + <<< \[aq][5,4,2,7]\[aq] +2 +.EE +.IP +.EX +$ jq \[aq]max_by(.foo)\[aq] \[rs] + <<< \[aq][{\[dq]foo\[dq]:1, \[dq]bar\[dq]:14}, {\[dq]foo\[dq]:2, \[dq]bar\[dq]:3}]\[aq] +{\[dq]foo\[dq]:2, \[dq]bar\[dq]:3} +.EE +.SS \f[CR]unique\f[R], \f[CR]unique_by(path_exp)\f[R] +The \f[CR]unique\f[R] function takes as input an array and produces an +array of the same elements, in sorted order, with duplicates removed. +.PP +The \f[CR]unique_by(path_exp)\f[R] function will keep only one element +for each value obtained by applying the argument. +Think of it as making an array by taking one element out of every group +produced by \f[CR]group\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]unique\[aq] \[rs] + <<< \[aq][1,2,5,3,5,3,1,3]\[aq] +[1,2,3,5] +.EE +.IP +.EX +$ jq \[aq]unique_by(.foo)\[aq] \[rs] + <<< \[aq][{\[dq]foo\[dq]: 1, \[dq]bar\[dq]: 2}, {\[dq]foo\[dq]: 1, \[dq]bar\[dq]: 3}, {\[dq]foo\[dq]: 4, \[dq]bar\[dq]: 5}]\[aq] +[{\[dq]foo\[dq]: 1, \[dq]bar\[dq]: 2}, {\[dq]foo\[dq]: 4, \[dq]bar\[dq]: 5}] +.EE +.IP +.EX +$ jq \[aq]unique_by(length)\[aq] \[rs] + <<< \[aq][\[dq]chunky\[dq], \[dq]bacon\[dq], \[dq]kitten\[dq], \[dq]cicada\[dq], \[dq]asparagus\[dq]]\[aq] +[\[dq]bacon\[dq], \[dq]chunky\[dq], \[dq]asparagus\[dq]] +.EE +.SS \f[CR]reverse\f[R] +This function reverses an array. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]reverse\[aq] \[rs] + <<< \[aq][1,2,3,4]\[aq] +[4,3,2,1] +.EE +.SS \f[CR]combinations\f[R], \f[CR]combinations(n)\f[R] +Outputs all combinations of the elements of the arrays in the input +array. +If given an argument \f[CR]n\f[R], it outputs all combinations of +\f[CR]n\f[R] repetitions of the input array. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]combinations\[aq] \[rs] + <<< \[aq][[1,2], [3, 4]]\[aq] +[1, 3] +[1, 4] +[2, 3] +[2, 4] +.EE +.IP +.EX +$ jq \[aq]combinations(2)\[aq] \[rs] + <<< \[aq][0, 1]\[aq] +[0, 0] +[0, 1] +[1, 0] +[1, 1] +.EE +.SS \f[CR]transpose\f[R] +Transpose a possibly jagged matrix (an array of arrays). +Rows are padded with nulls so the result is always rectangular. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]transpose\[aq] \[rs] + <<< \[aq][[1], [2,3]]\[aq] +[[1,2],[null,3]] +.EE +.SS \f[CR]flatten\f[R], \f[CR]flatten(depth)\f[R] +The filter \f[CR]flatten\f[R] takes as input an array of nested arrays, +and produces a flat array in which all arrays inside the original array +have been recursively replaced by their values. +You can pass an argument to it to specify how many levels of nesting to +flatten. +.PP +\f[CR]flatten(2)\f[R] is like \f[CR]flatten\f[R], but going only up to +two levels deep. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]flatten\[aq] \[rs] + <<< \[aq][1, [2], [[3]]]\[aq] +[1, 2, 3] +.EE +.IP +.EX +$ jq \[aq]flatten(1)\[aq] \[rs] + <<< \[aq][1, [2], [[3]]]\[aq] +[1, 2, [3]] +.EE +.IP +.EX +$ jq \[aq]flatten\[aq] \[rs] + <<< \[aq][[]]\[aq] +[] +.EE +.IP +.EX +$ jq \[aq]flatten\[aq] \[rs] + <<< \[aq][{\[dq]foo\[dq]: \[dq]bar\[dq]}, [{\[dq]foo\[dq]: \[dq]baz\[dq]}]]\[aq] +[{\[dq]foo\[dq]: \[dq]bar\[dq]}, {\[dq]foo\[dq]: \[dq]baz\[dq]}] +.EE +.SS String functions +.SS \f[CR]utf8bytelength\f[R] +The builtin function \f[CR]utf8bytelength\f[R] outputs the number of +bytes used to encode a string in UTF\-8. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]utf8bytelength\[aq] \[rs] + <<< \[aq]\[dq]\[rs]u03bc\[dq]\[aq] +2 +.EE +.SS \f[CR]startswith(str)\f[R] +Outputs \f[CR]true\f[R] if . +starts with the given string argument. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][.[]|startswith(\[dq]foo\[dq])]\[aq] \[rs] + <<< \[aq][\[dq]fo\[dq], \[dq]foo\[dq], \[dq]barfoo\[dq], \[dq]foobar\[dq], \[dq]barfoob\[dq]]\[aq] +[false, true, false, true, false] +.EE +.SS \f[CR]endswith(str)\f[R] +Outputs \f[CR]true\f[R] if . +ends with the given string argument. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][.[]|endswith(\[dq]foo\[dq])]\[aq] \[rs] + <<< \[aq][\[dq]foobar\[dq], \[dq]barfoo\[dq]]\[aq] +[false, true] +.EE +.SS \f[CR]ltrimstr(str)\f[R] +Outputs its input with the given prefix string removed, if it starts +with it. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][.[]|ltrimstr(\[dq]foo\[dq])]\[aq] \[rs] + <<< \[aq][\[dq]fo\[dq], \[dq]foo\[dq], \[dq]barfoo\[dq], \[dq]foobar\[dq], \[dq]afoo\[dq]]\[aq] +[\[dq]fo\[dq],\[dq]\[dq],\[dq]barfoo\[dq],\[dq]bar\[dq],\[dq]afoo\[dq]] +.EE +.SS \f[CR]rtrimstr(str)\f[R] +Outputs its input with the given suffix string removed, if it ends with +it. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][.[]|rtrimstr(\[dq]foo\[dq])]\[aq] \[rs] + <<< \[aq][\[dq]fo\[dq], \[dq]foo\[dq], \[dq]barfoo\[dq], \[dq]foobar\[dq], \[dq]foob\[dq]]\[aq] +[\[dq]fo\[dq],\[dq]\[dq],\[dq]bar\[dq],\[dq]foobar\[dq],\[dq]foob\[dq]] +.EE +.SS \f[CR]trim\f[R], \f[CR]ltrim\f[R], \f[CR]rtrim\f[R] +\f[CR]trim\f[R] trims both leading and trailing whitespace. +.PP +\f[CR]ltrim\f[R] trims only leading (left side) whitespace. +.PP +\f[CR]rtrim\f[R] trims only trailing (right side) whitespace. +.PP +Whitespace characters are the usual \f[CR]\[dq] \[dq]\f[R], +\f[CR]\[dq]\[rs]n\[dq]\f[R] \f[CR]\[dq]\[rs]t\[dq]\f[R], +\f[CR]\[dq]\[rs]r\[dq]\f[R] and also all characters in the Unicode +character database with the whitespace property. +Note that what considers whitespace might change in the future. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]trim, ltrim, rtrim\[aq] \[rs] + <<< \[aq]\[dq] abc \[dq]\[aq] +\[dq]abc\[dq] +\[dq]abc \[dq] +\[dq] abc\[dq] +.EE +.SS \f[CR]explode\f[R] +Converts an input string into an array of the string\[cq]s codepoint +numbers. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]explode\[aq] \[rs] + <<< \[aq]\[dq]foobar\[dq]\[aq] +[102,111,111,98,97,114] +.EE +.SS \f[CR]implode\f[R] +The inverse of explode. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]implode\[aq] \[rs] + <<< \[aq][65, 66, 67]\[aq] +\[dq]ABC\[dq] +.EE +.SS \f[CR]split(str)\f[R] +Splits an input string on the separator argument. +.PP +\f[CR]split\f[R] can also split on regex matches when called with two +arguments (see the regular expressions section below). +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]split(\[dq], \[dq])\[aq] \[rs] + <<< \[aq]\[dq]a, b,c,d, e, \[dq]\[aq] +[\[dq]a\[dq],\[dq]b,c,d\[dq],\[dq]e\[dq],\[dq]\[dq]] +.EE +.SS \f[CR]join(str)\f[R] +Joins the array of elements given as input, using the argument as +separator. +It is the inverse of \f[CR]split\f[R]: that is, running +\f[CR]split(\[dq]foo\[dq]) | join(\[dq]foo\[dq])\f[R] over any input +string returns said input string. +.PP +Numbers and booleans in the input are converted to strings. +Null values are treated as empty strings. +Arrays and objects in the input are not supported. +.TP +\f[I]Compatibility\f[R] +When given an array \f[CR][x0, x1, ..., xn]\f[R], in jq, +\f[CR]join(x)\f[R] converts all elements of the input array to strings +and intersperses them with \f[CR]x\f[R], whereas in jaq, +\f[CR]join(x)\f[R] simply calculates +\f[CR]x0 + x + x1 + x + ... + xn\f[R]. +When all elements of the input array and \f[CR]x\f[R] are strings, jq +and jaq yield the same output. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]join(\[dq], \[dq])\[aq] \[rs] + <<< \[aq][\[dq]a\[dq],\[dq]b,c,d\[dq],\[dq]e\[dq]]\[aq] +\[dq]a, b,c,d, e\[dq] +.EE +.IP +.EX +$ jq \[aq]join(\[dq] \[dq])\[aq] \[rs] + <<< \[aq][\[dq]a\[dq],1,2.3,true,null,false]\[aq] +\[dq]a 1 2.3 true false\[dq] +.EE +.SS \f[CR]ascii_downcase\f[R], \f[CR]ascii_upcase\f[R] +Emit a copy of the input string with its alphabetic characters (a\-z and +A\-Z) converted to the specified case. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]ascii_upcase\[aq] \[rs] + <<< \[aq]\[dq]useful but not for é\[dq]\[aq] +\[dq]USEFUL BUT NOT FOR é\[dq] +.EE +.SS String formatting functions +.SS \f[CR]\[at]text\f[R] +Calls \f[CR]tostring\f[R], see that function for details. +.SS \f[CR]\[at]json\f[R] +Serializes the input as JSON. +.SS \f[CR]\[at]html\f[R] +Applies HTML/XML escaping, by mapping the characters +\f[CR]<>&\[aq]\[dq]\f[R] to their entity equivalents \f[CR]<\f[R], +\f[CR]>\f[R], \f[CR]&\f[R], \f[CR]'\f[R], \f[CR]"\f[R]. +.SS \f[CR]\[at]uri\f[R] +Applies percent\-encoding, by mapping all reserved URI characters to a +\f[CR]%XX\f[R] sequence. +.SS \f[CR]\[at]urid\f[R] +The inverse of \f[CR]\[at]uri\f[R], applies percent\-decoding, by +mapping all \f[CR]%XX\f[R] sequences to their corresponding URI +characters. +.SS \f[CR]\[at]csv\f[R] +The input must be an array, and it is rendered as CSV with double quotes +for strings, and quotes escaped by repetition. +.SS \f[CR]\[at]tsv\f[R] +The input must be an array, and it is rendered as TSV (tab\-separated +values). +Each input array will be printed as a single line. +Fields are separated by a single tab (ascii \f[CR]0x09\f[R]). +Input characters line\-feed (ascii \f[CR]0x0a\f[R]), carriage\-return +(ascii \f[CR]0x0d\f[R]), tab (ascii \f[CR]0x09\f[R]) and backslash +(ascii \f[CR]0x5c\f[R]) will be output as escape sequences +\f[CR]\[rs]n\f[R], \f[CR]\[rs]r\f[R], \f[CR]\[rs]t\f[R], +\f[CR]\[rs]\[rs]\f[R] respectively. +.SS \f[CR]\[at]sh\f[R] +The input is escaped suitable for use in a command\-line for a POSIX +shell. +If the input is an array, the output will be a series of +space\-separated strings. +.SS \f[CR]\[at]base64\f[R] +The input is converted to base64 as specified by RFC 4648. +.SS \f[CR]\[at]base64d\f[R] +The inverse of \f[CR]\[at]base64\f[R], input is decoded as specified by +RFC 4648. +.TP +\f[I]Note\f[R] +If the decoded string is not UTF\-8, the results are undefined. +.SS Recursion functions +.SS \f[CR]repeat(f)\f[R] +The function \f[CR]repeat(f)\f[R] repeatedly runs \f[CR]f\f[R] on the +original input. +It could be naively defined via: +.IP +.EX +def repeat(f): f, repeat(f) +.EE +.TP +\f[I]Note\f[R] +\f[CR]repeat(f)\f[R] is internally defined as a recursive jq function. +Recursive calls within \f[CR]repeat\f[R] will not consume additional +memory if \f[CR]f\f[R] produces at most one output for each input. +See the section on recursion. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][repeat(.*2, error)?]\[aq] \[rs] + <<< \[aq]1\[aq] +[2] +.EE +.SS \f[CR]range(upto)\f[R], \f[CR]range(from; upto)\f[R], \f[CR]range(from; upto; by)\f[R] +The \f[CR]range\f[R] function produces a range of numbers. +\f[CR]range(4; 10)\f[R] produces 6 numbers, from 4 (inclusive) to 10 +(exclusive). +The numbers are produced as separate outputs. +Use \f[CR][range(4; 10)]\f[R] to get a range as an array. +.PP +The one argument form generates numbers from 0 to the given number, with +an increment of 1. +.PP +The two argument form generates numbers from \f[CR]from\f[R] to +\f[CR]upto\f[R] with an increment of 1. +.PP +The three argument form generates numbers \f[CR]from\f[R] to +\f[CR]upto\f[R] with an increment of \f[CR]by\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]range(2; 4)\[aq] \[rs] + <<< \[aq]null\[aq] +2 +3 +.EE +.IP +.EX +$ jq \[aq][range(2; 4)]\[aq] \[rs] + <<< \[aq]null\[aq] +[2,3] +.EE +.IP +.EX +$ jq \[aq][range(4)]\[aq] \[rs] + <<< \[aq]null\[aq] +[0,1,2,3] +.EE +.IP +.EX +$ jq \[aq][range(0; 10; 3)]\[aq] \[rs] + <<< \[aq]null\[aq] +[0,3,6,9] +.EE +.IP +.EX +$ jq \[aq][range(0; 10; \-1)]\[aq] \[rs] + <<< \[aq]null\[aq] +[] +.EE +.IP +.EX +$ jq \[aq][range(0; \-5; \-1)]\[aq] \[rs] + <<< \[aq]null\[aq] +[0,\-1,\-2,\-3,\-4] +.EE +.SS \f[CR]while(cond; update)\f[R] +The \f[CR]while(cond; update)\f[R] function allows you to repeatedly +apply an update to \f[CR].\f[R] until \f[CR]cond\f[R] is false. +.PP +Note that \f[CR]while(cond; update)\f[R] is internally defined as a +recursive jq function. +Recursive calls within \f[CR]while\f[R] will not consume additional +memory if \f[CR]update\f[R] produces at most one output for each input. +See advanced topics below. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][while(.<100; .*2)]\[aq] \[rs] + <<< \[aq]1\[aq] +[1,2,4,8,16,32,64] +.EE +.SS \f[CR]until(cond; next)\f[R] +The \f[CR]until(cond; next)\f[R] function allows you to repeatedly apply +the expression \f[CR]next\f[R], initially to \f[CR].\f[R] then to its +own output, until \f[CR]cond\f[R] is true. +For example, this can be used to implement a factorial function (see +below). +.PP +Note that \f[CR]until(cond; next)\f[R] is internally defined as a +recursive jq function. +Recursive calls within \f[CR]until()\f[R] will not consume additional +memory if \f[CR]next\f[R] produces at most one output for each input. +See advanced topics below. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][.,1]|until(.[0] < 1; [.[0] \- 1, .[1] * .[0]])|.[1]\[aq] \[rs] + <<< \[aq]4\[aq] +24 +.EE +.SS \f[CR]recurse(f)\f[R], \f[CR]recurse\f[R], \f[CR]recurse(f; condition)\f[R] +The \f[CR]recurse(f)\f[R] function allows you to search through a +recursive structure, and extract interesting data from all levels. +Suppose your input represents a filesystem: +.IP +.EX +{\[dq]name\[dq]: \[dq]/\[dq], \[dq]children\[dq]: [ + {\[dq]name\[dq]: \[dq]/bin\[dq], \[dq]children\[dq]: [ + {\[dq]name\[dq]: \[dq]/bin/ls\[dq], \[dq]children\[dq]: []}, + {\[dq]name\[dq]: \[dq]/bin/sh\[dq], \[dq]children\[dq]: []}]}, + {\[dq]name\[dq]: \[dq]/home\[dq], \[dq]children\[dq]: [ + {\[dq]name\[dq]: \[dq]/home/stephen\[dq], \[dq]children\[dq]: [ + {\[dq]name\[dq]: \[dq]/home/stephen/jq\[dq], \[dq]children\[dq]: []}]}]}]} +.EE +.PP +Now suppose you want to extract all of the filenames present. +You need to retrieve \f[CR].name\f[R], \f[CR].children[].name\f[R], +\f[CR].children[].children[].name\f[R], and so on. +You can do this with: +.IP +.EX +recurse(.children[]) | .name +.EE +.PP +When called without an argument, \f[CR]recurse\f[R] is equivalent to +\f[CR]recurse(.[]?)\f[R]. +.PP +\f[CR]recurse(f)\f[R] is identical to \f[CR]recurse(f; true)\f[R] and +can be used without concerns about recursion depth. +.PP +\f[CR]recurse(f; condition)\f[R] is a generator which begins by emitting +\&. +and then emits in turn .|f, .|f|f, .|f|f|f, \&... +so long as the computed value satisfies the condition. +For example, to generate all the integers, at least in principle, one +could write \f[CR]recurse(.+1; true)\f[R]. +.PP +The recursive calls in \f[CR]recurse\f[R] will not consume additional +memory whenever \f[CR]f\f[R] produces at most a single output for each +input. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]recurse(.foo[])\[aq] \[rs] + <<< \[aq]{\[dq]foo\[dq]:[{\[dq]foo\[dq]: []}, {\[dq]foo\[dq]:[{\[dq]foo\[dq]:[]}]}]}\[aq] +{\[dq]foo\[dq]:[{\[dq]foo\[dq]:[]},{\[dq]foo\[dq]:[{\[dq]foo\[dq]:[]}]}]} +{\[dq]foo\[dq]:[]} +{\[dq]foo\[dq]:[{\[dq]foo\[dq]:[]}]} +{\[dq]foo\[dq]:[]} +.EE +.IP +.EX +$ jq \[aq]recurse\[aq] \[rs] + <<< \[aq]{\[dq]a\[dq]:0,\[dq]b\[dq]:[1]}\[aq] +{\[dq]a\[dq]:0,\[dq]b\[dq]:[1]} +0 +[1] +1 +.EE +.IP +.EX +$ jq \[aq]recurse(. * .; . < 20)\[aq] \[rs] + <<< \[aq]2\[aq] +2 +4 +16 +.EE +.SS \f[CR]walk(f)\f[R] +The \f[CR]walk(f)\f[R] function applies f recursively to every component +of the input entity. +When an array is encountered, f is first applied to its elements and +then to the array itself; when an object is encountered, f is first +applied to all the values and then to the object. +In practice, f will usually test the type of its input, as illustrated +in the following examples. +The first example highlights the usefulness of processing the elements +of an array of arrays before processing the array itself. +The second example shows how all the keys of all the objects within the +input can be considered for alteration. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]walk(if type == \[dq]array\[dq] then sort else . end)\[aq] \[rs] + <<< \[aq][[4, 1, 7], [8, 5, 2], [3, 6, 9]]\[aq] +[[1,4,7],[2,5,8],[3,6,9]] +.EE +.IP +.EX +$ jq \[aq]walk( if type == \[dq]object\[dq] then with_entries( .key |= sub( \[dq]\[ha]_+\[dq]; \[dq]\[dq]) ) else . end )\[aq] \[rs] + <<< \[aq][ { \[dq]_a\[dq]: { \[dq]__b\[dq]: 2 } } ]\[aq] +[{\[dq]a\[dq]:{\[dq]b\[dq]:2}}] +.EE +.SS Stream processing functions +.SS \f[CR]isempty(expr)\f[R] +Returns true if \f[CR]expr\f[R] produces no outputs, false otherwise. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]isempty(empty)\[aq] \[rs] + <<< \[aq]null\[aq] +true +.EE +.IP +.EX +$ jq \[aq]isempty(.[])\[aq] \[rs] + <<< \[aq][]\[aq] +true +.EE +.IP +.EX +$ jq \[aq]isempty(.[])\[aq] \[rs] + <<< \[aq][1,2,3]\[aq] +false +.EE +.SS \f[CR]limit(n; expr)\f[R] +The \f[CR]limit\f[R] function extracts up to \f[CR]n\f[R] outputs from +\f[CR]expr\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][limit(3;.[])]\[aq] \[rs] + <<< \[aq][0,1,2,3,4,5,6,7,8,9]\[aq] +[0,1,2] +.EE +.SS \f[CR]skip(n; expr)\f[R] +The \f[CR]skip\f[R] function skips the first \f[CR]n\f[R] outputs from +\f[CR]expr\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][skip(3; .[])]\[aq] \[rs] + <<< \[aq][0,1,2,3,4,5,6,7,8,9]\[aq] +[3,4,5,6,7,8,9] +.EE +.SS \f[CR]first(expr)\f[R], \f[CR]last(expr)\f[R], \f[CR]nth(n; expr)\f[R] +The \f[CR]first(expr)\f[R] and \f[CR]last(expr)\f[R] functions extract +the first and last values from \f[CR]expr\f[R], respectively. +.PP +The \f[CR]nth(n; expr)\f[R] function extracts the nth value output by +\f[CR]expr\f[R]. +Note that \f[CR]nth(n; expr)\f[R] doesn\[cq]t support negative values of +\f[CR]n\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][first(range(.)), last(range(.)), nth(5; range(.))]\[aq] \[rs] + <<< \[aq]10\[aq] +[0,9,5] +.EE +.IP +.EX +$ jq \[aq][first(empty), last(empty), nth(5; empty)]\[aq] \[rs] + <<< \[aq]null\[aq] +[] +.EE +.SS \f[CR]first\f[R], \f[CR]last\f[R], \f[CR]nth(n)\f[R] +The \f[CR]first\f[R] and \f[CR]last\f[R] functions extract the first and +last values from any array at \f[CR].\f[R]. +.PP +The \f[CR]nth(n)\f[R] function extracts the nth value of any array at +\f[CR].\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][range(.)]|[first, last, nth(5)]\[aq] \[rs] + <<< \[aq]10\[aq] +[0,9,5] +.EE +.SS JSON conversion functions +.SS \f[CR]tojson\f[R], \f[CR]fromjson\f[R] +The \f[CR]tojson\f[R] and \f[CR]fromjson\f[R] builtins dump values as +JSON texts or parse JSON texts into values, respectively. +The \f[CR]tojson\f[R] builtin differs from \f[CR]tostring\f[R] in that +\f[CR]tostring\f[R] returns strings unmodified, while \f[CR]tojson\f[R] +encodes strings as JSON strings. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][.[]|tostring]\[aq] \[rs] + <<< \[aq][1, \[dq]foo\[dq], [\[dq]foo\[dq]]]\[aq] +[\[dq]1\[dq],\[dq]foo\[dq],\[dq][\[rs]\[dq]foo\[rs]\[dq]]\[dq]] +.EE +.IP +.EX +$ jq \[aq][.[]|tojson]\[aq] \[rs] + <<< \[aq][1, \[dq]foo\[dq], [\[dq]foo\[dq]]]\[aq] +[\[dq]1\[dq],\[dq]\[rs]\[dq]foo\[rs]\[dq]\[dq],\[dq][\[rs]\[dq]foo\[rs]\[dq]]\[dq]] +.EE +.IP +.EX +$ jq \[aq][.[]|tojson|fromjson]\[aq] \[rs] + <<< \[aq][1, \[dq]foo\[dq], [\[dq]foo\[dq]]]\[aq] +[1,\[dq]foo\[dq],[\[dq]foo\[dq]]] +.EE +.SS \f[CR]tostring\f[R] +The \f[CR]tostring\f[R] function prints its input as a string. +Strings are left unchanged, and all other values are JSON\-encoded. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[] | tostring\[aq] \[rs] + <<< \[aq][1, \[dq]1\[dq], [1]]\[aq] +\[dq]1\[dq] +\[dq]1\[dq] +\[dq][1]\[dq] +.EE +.SS \f[CR]tonumber\f[R] +The \f[CR]tonumber\f[R] function parses its input as a number. +It will convert correctly\-formatted strings to their numeric +equivalent, leave numbers alone, and give an error on all other input. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq].[] | tonumber\[aq] \[rs] + <<< \[aq][1, \[dq]1\[dq]]\[aq] +1 +1 +.EE +.SS Date functions +jq provides some basic date handling functionality, with some +high\-level and low\-level builtins. +In all cases these builtins deal exclusively with time in UTC. +.SS High\-level date functions +The \f[CR]fromdateiso8601\f[R] builtin parses datetimes in the ISO 8601 +format to a number of seconds since the Unix epoch +(1970\-01\-01T00:00:00Z). +The \f[CR]todateiso8601\f[R] builtin does the inverse. +.PP +The \f[CR]fromdate\f[R] builtin parses datetime strings. +Currently \f[CR]fromdate\f[R] only supports ISO 8601 datetime strings, +but in the future it will attempt to parse datetime strings in more +formats. +.PP +The \f[CR]todate\f[R] builtin is an alias for \f[CR]todateiso8601\f[R]. +.PP +The \f[CR]now\f[R] builtin outputs the current time, in seconds since +the Unix epoch. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]fromdate\[aq] \[rs] + <<< \[aq]\[dq]2015\-03\-05T23:51:47Z\[dq]\[aq] +1425599507 +.EE +.SS Low\-level date functions +Low\-level jq interfaces to the C\-library time functions are also +provided: \f[CR]strptime\f[R], \f[CR]strftime\f[R], +\f[CR]strflocaltime\f[R], \f[CR]mktime\f[R], \f[CR]gmtime\f[R], and +\f[CR]localtime\f[R]. +Refer to your host operating system\[cq]s documentation for the format +strings used by \f[CR]strptime\f[R] and \f[CR]strftime\f[R]. +Note: these are not necessarily stable interfaces in jq, particularly as +to their localization functionality. +.PP +The \f[CR]gmtime\f[R] builtin consumes a number of seconds since the +Unix epoch and outputs a \[lq]broken down time\[rq] representation of +Greenwich Mean Time as an array of numbers representing (in this order): +the year, the month (zero\-based), the day of the month (one\-based), +the hour of the day, the minute of the hour, the second of the minute, +the day of the week, and the day of the year \[en] all one\-based unless +otherwise stated. +The day of the week number may be wrong on some systems for dates before +March 1st 1900, or after December 31 2099. +.PP +The \f[CR]localtime\f[R] builtin works like the \f[CR]gmtime\f[R] +builtin, but using the local timezone setting. +.PP +The \f[CR]mktime\f[R] builtin consumes \[lq]broken down time\[rq] +representations of time output by \f[CR]gmtime\f[R] and +\f[CR]strptime\f[R]. +.PP +The \f[CR]strptime(fmt)\f[R] builtin parses input strings matching the +\f[CR]fmt\f[R] argument. +The output is in the \[lq]broken down time\[rq] representation consumed +by \f[CR]mktime\f[R] and output by \f[CR]gmtime\f[R]. +.PP +The \f[CR]strftime(fmt)\f[R] builtin formats a time (GMT) with the given +format. +The \f[CR]strflocaltime\f[R] does the same, but using the local timezone +setting. +.PP +The format strings for \f[CR]strptime\f[R] and \f[CR]strftime\f[R] are +described in typical C library documentation. +The format string for ISO 8601 datetime is +\f[CR]\[dq]%Y\-%m\-%dT%H:%M:%SZ\[dq]\f[R]. +.PP +jq may not support some or all of this date functionality on some +systems. +In particular, the \f[CR]%u\f[R] and \f[CR]%j\f[R] specifiers for +\f[CR]strptime(fmt)\f[R] are not supported on macOS. +.TP +\f[I]Compatibility\f[R] +jaq does not provide any of the given low\-level date functions. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]strptime(\[dq]%Y\-%m\-%dT%H:%M:%SZ\[dq])\[aq] \[rs] + <<< \[aq]\[dq]2015\-03\-05T23:51:47Z\[dq]\[aq] +[2015,2,5,23,51,47,4,63] +.EE +.IP +.EX +$ jq \[aq]strptime(\[dq]%Y\-%m\-%dT%H:%M:%SZ\[dq])|mktime\[aq] \[rs] + <<< \[aq]\[dq]2015\-03\-05T23:51:47Z\[dq]\[aq] +1425599507 +.EE +.SS SQL\-style functions +jq provides a few SQL\-style functions. +.TP +\f[I]Compatibility\f[R] +jaq does not provide any of the functions in this subsection. +.SS \f[CR]INDEX(stream; index_expression)\f[R] +This builtin produces an object whose keys are computed by the given +index expression applied to each value from the given stream. +.SS \f[CR]JOIN($idx; stream; idx_expr; join_expr)\f[R] +This builtin joins the values from the given stream to the given index. +The index\[cq]s keys are computed by applying the given index expression +to each value from the given stream. +An array of the value in the stream and the corresponding value from the +index is fed to the given join expression to produce each result. +.SS \f[CR]JOIN($idx; stream; idx_expr)\f[R] +Same as \f[CR]JOIN($idx; stream; idx_expr; .)\f[R]. +.SS \f[CR]JOIN($idx; idx_expr)\f[R] +This builtin joins the input \f[CR].\f[R] to the given index, applying +the given index expression to \f[CR].\f[R] to compute the index key. +The join operation is as described above. +.SS \f[CR]IN(s)\f[R] +This builtin outputs \f[CR]true\f[R] if \f[CR].\f[R] appears in the +given stream, otherwise it outputs \f[CR]false\f[R]. +.SS \f[CR]IN(source; s)\f[R] +This builtin outputs \f[CR]true\f[R] if any value in the source stream +appears in the second stream, otherwise it outputs \f[CR]false\f[R]. +.SS Regular expression functions +jq uses the \c +.UR https://github.com/kkos/oniguruma/blob/master/doc/RE +Oniguruma regular expression library +.UE \c +, as do PHP, TextMate, Sublime Text, etc, so the description here will +focus on jq specifics. +.PP +Oniguruma supports several flavors of regular expression, so it is +important to know that jq uses the \c +.UR https://github.com/kkos/oniguruma/blob/master/doc/SYNTAX.md +\[lq]Perl NG\[rq] (Perl with named groups) +.UE \c +\ flavor. +.PP +The jq regex filters are defined so that they can be used using one of +these patterns: +.IP +.EX +STRING | FILTER(REGEX) +STRING | FILTER(REGEX; FLAGS) +STRING | FILTER([REGEX]) +STRING | FILTER([REGEX, FLAGS]) +.EE +.PP +where: +.IP \[bu] 2 +STRING, REGEX, and FLAGS are jq strings and subject to jq string +interpolation; +.IP \[bu] 2 +REGEX, after string interpolation, should be a valid regular expression; +.IP \[bu] 2 +FILTER is one of \f[CR]test\f[R], \f[CR]match\f[R], or +\f[CR]capture\f[R], as described below. +.PP +Since REGEX must evaluate to a JSON string, some characters that are +needed to form a regular expression must be escaped. +For example, the regular expression \f[CR]\[rs]s\f[R] signifying a +whitespace character would be written as +\f[CR]\[dq]\[rs]\[rs]s\[dq]\f[R]. +.PP +FLAGS is a string consisting of one of more of the supported flags: +.IP \[bu] 2 +\f[CR]g\f[R] \- Global search (find all matches, not just the first) +.IP \[bu] 2 +\f[CR]i\f[R] \- Case insensitive search +.IP \[bu] 2 +\f[CR]m\f[R] \- Multi line mode (\f[CR].\f[R] will match newlines) +.IP \[bu] 2 +\f[CR]n\f[R] \- Ignore empty matches +.IP \[bu] 2 +\f[CR]p\f[R] \- Both s and m modes are enabled +.IP \[bu] 2 +\f[CR]s\f[R] \- Single line mode (\f[CR]\[ha]\f[R] \-> +\f[CR]\[rs]A\f[R], \f[CR]$\f[R] \-> \f[CR]\[rs]Z\f[R]) +.IP \[bu] 2 +\f[CR]l\f[R] \- Find longest possible matches +.IP \[bu] 2 +\f[CR]x\f[R] \- Extended regex format (ignore whitespace and comments) +.PP +To match a whitespace with the \f[CR]x\f[R] flag, use \f[CR]\[rs]s\f[R], +e.g. +.IP +.EX +jq \-n \[aq]\[dq]a b\[dq] | test(\[dq]a\[rs]\[rs]sb\[dq]; \[dq]x\[dq])\[aq] +.EE +.PP +Note that certain flags may also be specified within REGEX, e.g. +.IP +.EX +jq \-n \[aq](\[dq]test\[dq], \[dq]TEst\[dq], \[dq]teST\[dq], \[dq]TEST\[dq]) | test(\[dq](?i)te(?\-i)st\[dq])\[aq] +.EE +.PP +evaluates to \f[CR]true\f[R], \f[CR]true\f[R], \f[CR]false\f[R], +\f[CR]false\f[R]. +.TP +\f[I]Compatibility\f[R] +jaq uses the \c +.UR https://docs.rs/regex/latest/regex/ +\f[CR]regex\f[R] library +.UE \c +\ instead of Oniguruma, which can result in subtle differences in regex +execution. +.SS \f[CR]test(val)\f[R], \f[CR]test(regex; flags)\f[R] +Like \f[CR]match\f[R], but does not return match objects, only +\f[CR]true\f[R] or \f[CR]false\f[R] for whether or not the regex matches +the input. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]test(\[dq]foo\[dq])\[aq] \[rs] + <<< \[aq]\[dq]foo\[dq]\[aq] +true +.EE +.IP +.EX +$ jq \[aq].[] | test(\[dq]a b c # spaces are ignored\[dq]; \[dq]ix\[dq])\[aq] \[rs] + <<< \[aq][\[dq]xabcd\[dq], \[dq]ABC\[dq]]\[aq] +true +true +.EE +.SS \f[CR]match(val)\f[R], \f[CR]match(regex; flags)\f[R] +\f[B]match\f[R] outputs an object for each match it finds. +Matches have the following fields: +.IP \[bu] 2 +\f[CR]offset\f[R] \- offset in UTF\-8 codepoints from the beginning of +the input +.IP \[bu] 2 +\f[CR]length\f[R] \- length in UTF\-8 codepoints of the match +.IP \[bu] 2 +\f[CR]string\f[R] \- the string that it matched +.IP \[bu] 2 +\f[CR]captures\f[R] \- an array of objects representing capturing +groups. +.PP +Capturing group objects have the following fields: +.IP \[bu] 2 +\f[CR]offset\f[R] \- offset in UTF\-8 codepoints from the beginning of +the input +.IP \[bu] 2 +\f[CR]length\f[R] \- length in UTF\-8 codepoints of this capturing group +.IP \[bu] 2 +\f[CR]string\f[R] \- the string that was captured +.IP \[bu] 2 +\f[CR]name\f[R] \- the name of the capturing group (or \f[CR]null\f[R] +if it was unnamed) +.PP +Capturing groups that did not match anything return an offset of \-1 +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]match(\[dq](abc)+\[dq]; \[dq]g\[dq])\[aq] \[rs] + <<< \[aq]\[dq]abc abc\[dq]\[aq] +{\[dq]offset\[dq]: 0, \[dq]length\[dq]: 3, \[dq]string\[dq]: \[dq]abc\[dq], \[dq]captures\[dq]: [{\[dq]offset\[dq]: 0, \[dq]length\[dq]: 3, \[dq]string\[dq]: \[dq]abc\[dq], \[dq]name\[dq]: null}]} +{\[dq]offset\[dq]: 4, \[dq]length\[dq]: 3, \[dq]string\[dq]: \[dq]abc\[dq], \[dq]captures\[dq]: [{\[dq]offset\[dq]: 4, \[dq]length\[dq]: 3, \[dq]string\[dq]: \[dq]abc\[dq], \[dq]name\[dq]: null}]} +.EE +.IP +.EX +$ jq \[aq]match(\[dq]foo\[dq])\[aq] \[rs] + <<< \[aq]\[dq]foo bar foo\[dq]\[aq] +{\[dq]offset\[dq]: 0, \[dq]length\[dq]: 3, \[dq]string\[dq]: \[dq]foo\[dq], \[dq]captures\[dq]: []} +.EE +.IP +.EX +$ jq \[aq]match([\[dq]foo\[dq], \[dq]ig\[dq]])\[aq] \[rs] + <<< \[aq]\[dq]foo bar FOO\[dq]\[aq] +{\[dq]offset\[dq]: 0, \[dq]length\[dq]: 3, \[dq]string\[dq]: \[dq]foo\[dq], \[dq]captures\[dq]: []} +{\[dq]offset\[dq]: 8, \[dq]length\[dq]: 3, \[dq]string\[dq]: \[dq]FOO\[dq], \[dq]captures\[dq]: []} +.EE +.IP +.EX +$ jq \[aq]match(\[dq]foo (?bar)? foo\[dq]; \[dq]ig\[dq])\[aq] \[rs] + <<< \[aq]\[dq]foo bar foo foo foo\[dq]\[aq] +{\[dq]offset\[dq]: 0, \[dq]length\[dq]: 11, \[dq]string\[dq]: \[dq]foo bar foo\[dq], \[dq]captures\[dq]: [{\[dq]offset\[dq]: 4, \[dq]length\[dq]: 3, \[dq]string\[dq]: \[dq]bar\[dq], \[dq]name\[dq]: \[dq]bar123\[dq]}]} +{\[dq]offset\[dq]: 12, \[dq]length\[dq]: 8, \[dq]string\[dq]: \[dq]foo foo\[dq], \[dq]captures\[dq]: [{\[dq]offset\[dq]: \-1, \[dq]length\[dq]: 0, \[dq]string\[dq]: null, \[dq]name\[dq]: \[dq]bar123\[dq]}]} +.EE +.IP +.EX +$ jq \[aq][ match(\[dq].\[dq]; \[dq]g\[dq])] | length\[aq] \[rs] + <<< \[aq]\[dq]abc\[dq]\[aq] +3 +.EE +.SS \f[CR]capture(val)\f[R], \f[CR]capture(regex; flags)\f[R] +Collects the named captures in a JSON object, with the name of each +capture as the key, and the matched string as the corresponding value. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]capture(\[dq](?[a\-z]+)\-(?[0\-9]+)\[dq])\[aq] \[rs] + <<< \[aq]\[dq]xyzzy\-14\[dq]\[aq] +{ \[dq]a\[dq]: \[dq]xyzzy\[dq], \[dq]n\[dq]: \[dq]14\[dq] } +.EE +.SS \f[CR]scan(regex)\f[R], \f[CR]scan(regex; flags)\f[R] +Emit a stream of the non\-overlapping substrings of the input that match +the regex in accordance with the flags, if any have been specified. +If there is no match, the stream is empty. +To capture all the matches for each input string, use the idiom +\f[CR][ expr ]\f[R], e.g.\ \f[CR][ scan(regex) ]\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]scan(\[dq]c\[dq])\[aq] \[rs] + <<< \[aq]\[dq]abcdefabc\[dq]\[aq] +\[dq]c\[dq] +\[dq]c\[dq] +.EE +.SS \f[CR]split(regex; flags)\f[R] +Splits an input string on each regex match. +.PP +For backwards compatibility, when called with a single argument, +\f[CR]split\f[R] splits on a string, not a regex. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]split(\[dq], *\[dq]; null)\[aq] \[rs] + <<< \[aq]\[dq]ab,cd, ef\[dq]\[aq] +[\[dq]ab\[dq],\[dq]cd\[dq],\[dq]ef\[dq]] +.EE +.SS \f[CR]splits(regex)\f[R], \f[CR]splits(regex; flags)\f[R] +These provide the same results as their \f[CR]split\f[R] counterparts, +but as a stream instead of an array. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]splits(\[dq], *\[dq])\[aq] \[rs] + <<< \[aq]\[dq]ab,cd, ef, gh\[dq]\[aq] +\[dq]ab\[dq] +\[dq]cd\[dq] +\[dq]ef\[dq] +\[dq]gh\[dq] +.EE +.SS \f[CR]sub(regex; tostring)\f[R], \f[CR]sub(regex; tostring; flags)\f[R] +Emit the string obtained by replacing the first match of regex in the +input string with \f[CR]tostring\f[R], after interpolation. +\f[CR]tostring\f[R] should be a jq string or a stream of such strings, +each of which may contain references to named captures. +The named captures are, in effect, presented as a JSON object (as +constructed by \f[CR]capture\f[R]) to \f[CR]tostring\f[R], so a +reference to a captured variable named \[lq]x\[rq] would take the form: +\f[CR]\[dq]\[rs](.x)\[dq]\f[R]. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]sub(\[dq][\[ha]a\-z]*(?[a\-z]+)\[dq]; \[dq]Z\[rs](.x)\[dq]; \[dq]g\[dq])\[aq] \[rs] + <<< \[aq]\[dq]123abc456def\[dq]\[aq] +\[dq]ZabcZdef\[dq] +.EE +.IP +.EX +$ jq \[aq][sub(\[dq](?.)\[dq]; \[dq]\[rs](.a|ascii_upcase)\[dq], \[dq]\[rs](.a|ascii_downcase)\[dq])]\[aq] \[rs] + <<< \[aq]\[dq]aB\[dq]\[aq] +[\[dq]AB\[dq],\[dq]aB\[dq]] +.EE +.SS \f[CR]gsub(regex; tostring)\f[R], \f[CR]gsub(regex; tostring; flags)\f[R] +\f[CR]gsub\f[R] is like \f[CR]sub\f[R] but all the non\-overlapping +occurrences of the regex are replaced by \f[CR]tostring\f[R], after +interpolation. +If the second argument is a stream of jq strings, then \f[CR]gsub\f[R] +will produce a corresponding stream of JSON strings. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]gsub(\[dq](?.)[\[ha]a]*\[dq]; \[dq]+\[rs](.x)\-\[dq])\[aq] \[rs] + <<< \[aq]\[dq]Abcabc\[dq]\[aq] +\[dq]+A\-+a\-\[dq] +.EE +.IP +.EX +$ jq \[aq][gsub(\[dq]p\[dq]; \[dq]a\[dq], \[dq]b\[dq])]\[aq] \[rs] + <<< \[aq]\[dq]p\[dq]\[aq] +[\[dq]a\[dq],\[dq]b\[dq]] +.EE +.SS I/O functions +At this time jq has minimal support for I/O, mostly in the form of +control over when inputs are read. +Two builtins functions are provided for this, \f[CR]input\f[R] and +\f[CR]inputs\f[R], that read from the same sources (e.g., +\f[CR]stdin\f[R], files named on the command\-line) as jq itself. +These two builtins, and jq\[cq]s own reading actions, can be interleaved +with each other. +They are commonly used in combination with the null input option +\f[CR]\-n\f[R] to prevent one input from being read implicitly. +.PP +Two builtins provide minimal output capabilities, \f[CR]debug\f[R], and +\f[CR]stderr\f[R]. +(Recall that a jq program\[cq]s output values are always output as JSON +texts on \f[CR]stdout\f[R].) +The \f[CR]debug\f[R] builtin can have application\-specific behavior, +such as for executables that use the libjq C API but aren\[cq]t the jq +executable itself. +The \f[CR]stderr\f[R] builtin outputs its input in raw mode to stder +with no additional decoration, not even a newline. +.PP +Most jq builtins are referentially transparent, and yield constant and +repeatable value streams when applied to constant inputs. +This is not true of I/O builtins. +.SS \f[CR]input\f[R], \f[CR]inputs\f[R] +The filter \f[CR]input\f[R] outputs one new input, and the filter +\f[CR]inputs\f[R] outputs all remaining inputs. +This is primarily useful for reductions over a program\[cq]s inputs. +.TP +\f[I]Note\f[R] +When using \f[CR]input\f[R] or \f[CR]inputs\f[R], it is often necessary +to invoke jq with the \f[CR]\-n\f[R] command\-line option to avoid +losing the first value in the input stream. +.IP +.EX +$ echo 1 2 3 4 | jq \[aq][., input]\[aq] +[1,2] +[3,4] +$ echo 1 2 3 | jq \-n \[aq]reduce inputs as $i (0; . + $i)\[aq] +6 +.EE +.TP +\f[I]Compatibility\f[R] +When there is no more input value left, in jq, \f[CR]input\f[R] yields +an error, whereas in jaq, \f[CR]input\f[R] yields no output value, +i.e.\ \f[CR]empty\f[R]. +.SS \f[CR]debug\f[R], \f[CR]debug(msgs)\f[R] +These two filters are like \f[CR].\f[R] but have as a side\-effect the +production of one or more messages on stderr. +.PP +The message produced by the \f[CR]debug\f[R] filter has the form +.IP +.EX +[\[dq]DEBUG:\[dq],] +.EE +.PP +where \f[CR]\f[R] is a compact rendition of the input +value. +This format may change in the future. +.PP +The \f[CR]debug(msgs)\f[R] filter is defined as +\f[CR](msgs | debug | empty), .\f[R] thus allowing great flexibility in +the content of the message, while also allowing multi\-line debugging +statements to be created. +.PP +For example, the expression: +.IP +.EX +1 as $x | 2 | debug(\[dq]Entering function foo with $x == \[rs]($x)\[dq], .) | (.+1) +.EE +.PP +would produce the value 3 but with the following two lines being written +to stderr: +.IP +.EX +[\[dq]DEBUG:\[dq],\[dq]Entering function foo with $x == 1\[dq]] +[\[dq]DEBUG:\[dq],2] +.EE +.SS \f[CR]stderr\f[R] +Prints its input in raw and compact mode to stderr with no additional +decoration, not even a newline. +.SS \f[CR]halt\f[R] +Stops the jq program with no further outputs. +jq will exit with exit status \f[CR]0\f[R]. +.SS \f[CR]halt_error\f[R], \f[CR]halt_error(exit_code)\f[R] +Stops the jq program with no further outputs. +The input will be printed on \f[CR]stderr\f[R] as raw output (i.e., +strings will not have double quotes) with no decoration, not even a +newline. +.PP +The given \f[CR]exit_code\f[R] (defaulting to \f[CR]5\f[R]) will be +jq\[cq]s exit status. +.PP +For example, +\f[CR]\[dq]Error: something went wrong\[rs]n\[dq]|halt_error(1)\f[R]. +.SS \f[CR]input_filename\f[R] +Returns the name of the file whose input is currently being filtered. +Note that this will not work well unless jq is running in a UTF\-8 +locale. +.TP +\f[I]Compatibility\f[R] +jaq does not provide this function. +.SS \f[CR]input_line_number\f[R] +Returns the line number of the input currently being filtered. +.TP +\f[I]Compatibility\f[R] +jaq does not provide this function. +.SS \f[CR]$ENV\f[R], \f[CR]env\f[R] +\f[CR]$ENV\f[R] is an object representing the environment variables as +set when the jq program started. +.PP +\f[CR]env\f[R] outputs an object representing jq\[cq]s current +environment. +.PP +At the moment there is no builtin for setting environment variables. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]$ENV.PAGER\[aq] \[rs] + <<< \[aq]null\[aq] +\[dq]less\[dq] +.EE +.IP +.EX +$ jq \[aq]env.PAGER\[aq] \[rs] + <<< \[aq]null\[aq] +\[dq]less\[dq] +.EE +.SS Streaming functions +With the \f[CR]\-\-stream\f[R] option jq can parse input texts in a +streaming fashion, allowing jq programs to start processing large JSON +texts immediately rather than after the parse completes. +If you have a single JSON text that is 1GB in size, streaming it will +allow you to process it much more quickly. +.PP +However, streaming isn\[cq]t easy to deal with as the jq program will +have \f[CR][, ]\f[R] (and a few other forms) as +inputs. +.PP +Several builtins are provided to make handling streams easier. +.PP +The examples below use the streamed form of \f[CR][0,[1]]\f[R], which is +\f[CR][[0],0],[[1,0],1],[[1,0]],[[1]]\f[R]. +.PP +Streaming forms include \f[CR][, ]\f[R] (to indicate +any scalar value, empty array, or empty object), and \f[CR][]\f[R] +(to indicate the end of an array or object). +Future versions of jq run with \f[CR]\-\-stream\f[R] and +\f[CR]\-\-seq\f[R] may output additional forms such as +\f[CR][\[dq]error message\[dq]]\f[R] when an input text fails to parse. +.TP +\f[I]Compatibility\f[R] +Because jaq does not support the \f[CR]\-\-stream\f[R] option, it does +not provide any of the functions in this subsection. +.SS \f[CR]truncate_stream(stream_expression)\f[R] +Consumes a number as input and truncates the corresponding number of +path elements from the left of the outputs of the given streaming +expression. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]])\[aq] \[rs] + <<< \[aq]1\[aq] +[[0],2] +[[0]] +.EE +.SS \f[CR]fromstream(stream_expression)\f[R] +Outputs values corresponding to the stream expression\[cq]s outputs. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]fromstream(1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]]))\[aq] \[rs] + <<< \[aq]null\[aq] +[2] +.EE +.SS \f[CR]tostream\f[R] +The \f[CR]tostream\f[R] builtin outputs the streamed form of its input. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]. as $dot|fromstream($dot|tostream)|.==$dot\[aq] \[rs] + <<< \[aq][0,[1,{\[dq]a\[dq]:1},{\[dq]b\[dq]:2}]]\[aq] +true +.EE +.SS Miscellaneous +.TP +\f[I]Compatibility\f[R] +jaq does not provide any of the symbols in this subsection. +.SS \f[CR]modulemeta\f[R] +Takes a module name as input and outputs the module\[cq]s metadata as an +object, with the module\[cq]s imports (including metadata) as an array +value for the \f[CR]deps\f[R] key and the module\[cq]s defined functions +as an array value for the \f[CR]defs\f[R] key. +.PP +Programs can use this to query a module\[cq]s metadata, which they could +then use to, for example, search for, download, and install missing +dependencies. +.SS \f[CR]$__loc__\f[R] +Produces an object with a \[lq]file\[rq] key and a \[lq]line\[rq] key, +with the filename and line number where \f[CR]$__loc__\f[R] occurs, as +values. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq]try error(\[dq]\[rs]($__loc__)\[dq]) catch .\[aq] \[rs] + <<< \[aq]null\[aq] +\[dq]{\[rs]\[dq]file\[rs]\[dq]:\[rs]\[dq]\[rs]\[dq],\[rs]\[dq]line\[rs]\[dq]:1}\[dq] +.EE +.SS \f[CR]builtins\f[R] +Returns a list of all builtin functions in the format +\f[CR]name/arity\f[R]. +Since functions with the same name but different arities are considered +separate functions, \f[CR]all/0\f[R], \f[CR]all/1\f[R], and +\f[CR]all/2\f[R] would all be present in the list. +.SS \f[CR]have_literal_numbers\f[R] +This builtin returns true if jq\[cq]s build configuration includes +support for preservation of input number literals. +.SS \f[CR]have_decnum\f[R] +This builtin returns true if jq was built with \[lq]decnum\[rq], which +is the current literal number preserving numeric backend implementation +for jq. +.PP +The examples below use the builtin function \f[CR]have_decnum\f[R] in +order to demonstrate the expected effects of using / not using +\f[CR]\-\-disable\-decnum\f[R]. +They also allow automated tests derived from these examples to pass +regardless of whether that option is used. +.TP +\f[I]Examples\f[R] +.IP +.EX +$ jq \[aq][., tojson] | . == if have_decnum then [12345678909876543212345,\[dq]12345678909876543212345\[dq]] else [12345678909876543000000,\[dq]12345678909876543000000\[dq]] end\[aq] \[rs] + <<< \[aq]12345678909876543212345\[aq] +true +.EE +.IP +.EX +$ jq \[aq]map([., . == 1]) | tojson | . == if have_decnum then \[dq][[1,true],[1.000,true],[1.0,true],[1.00,true]]\[dq] else \[dq][[1,true],[1,true],[1,true],[1,true]]\[dq] end\[aq] \[rs] + <<< \[aq][1, 1.000, 1.0, 100e\-2]\[aq] +true +.EE +.IP +.EX +$ jq \[aq]. as $big | [$big, $big + 1] | map(. > 10000000000000000000000000000000) | . == if have_decnum then [true, false] else [false, false] end\[aq] \[rs] + <<< \[aq]10000000000000000000000000000001\[aq] +true +.EE +.SS \f[CR]$JQ_BUILD_CONFIGURATION\f[R] +This builtin variable shows the jq executable\[cq]s build configuration. +Its value has no particular format, but it can be expected to be at +least the \f[CR]./configure\f[R] command\-line arguments, and may be +enriched in the future to include the version strings for the build +tooling used. +.PP +Note that this can be overridden in the command\-line with +\f[CR]\-\-arg\f[R] and related options. +.SH BUGS +Presumably. +Report them or discuss them at: +.IP +.EX +https://github.com/jqlang/jq/issues +.EE +.SH AUTHOR +Stephen Dolan \f[CR]\f[R] diff --git a/tests/man.test b/tests/man.test index e69de29bb2..a9d3720895 100644 --- a/tests/man.test +++ b/tests/man.test @@ -0,0 +1,1038 @@ +. < 0.12345678901234567890123456788 +0.12345678901234567890123456789 +false + +"The input was \(.), which is one less than \(.+1)" +42 +"The input was 42, which is one less than 43" + +@html +"This works if x < y" +"This works if x < y" + +@sh "echo \(.)" +"O'Hara's Ale" +"echo 'O'\\''Hara'\\''s Ale'" + +@base64 +"This is a message" +"VGhpcyBpcyBhIG1lc3NhZ2U=" + +@base64d +"VGhpcyBpcyBhIG1lc3NhZ2U=" +"This is a message" + +[.user, .projects[]] +{"user":"stedolan", "projects": ["jq", "wikiflow"]} +["stedolan", "jq", "wikiflow"] + +[.[] | . * 2] +[1, 2, 3] +[2, 4, 6] + +{user, title: .titles[]} +{"user":"stedolan","titles":["JQ Primer", "More JQ"]} +{"user":"stedolan", "title": "JQ Primer"} +{"user":"stedolan", "title": "More JQ"} + +{(.user): .titles} +{"user":"stedolan","titles":["JQ Primer", "More JQ"]} +{"stedolan": ["JQ Primer", "More JQ"]} + +{foo: .bar} +{"bar":42, "baz":43} +{"foo": 42}. + +. +"Hello, world!" +"Hello, world!" + +. +0.12345678901234567890123456789 +0.12345678901234567890123456789 + +.foo, .bar +{"foo": 42, "bar": "something else", "baz": true} +42 +"something else" + +.user, .projects[] +{"user":"stedolan", "projects": ["jq", "wikiflow"]} +"stedolan" +"jq" +"wikiflow" + +.[4,2] +["a","b","c","d","e"] +"e" +"c" + +.[] | .name +[{"name":"JSON", "good":true}, {"name":"XML", "good":false}] +"JSON" +"XML" + +length +[1, 1, 2, 3] +4 + +add(range(0; .)) +2 +3 + +while(length < 3; . + "a") +"" +"" +"a" +"aa" + +(. + 2) * 5 +1 +15 + +.. | .a? +[[{"a":1}]] +1 + +.[] +[{"name":"JSON", "good":true}, {"name":"XML", "good":false}] +{"name":"JSON", "good":true} +{"name":"XML", "good":false} + +.[] +[] + + +.foo[] +{"foo":[1,2,3]} +1 +2 +3 + +.[] +{"a": 1, "b": 2} +1 +2 + +.foo +{"foo": 42, "bar": "less interesting data"} +42 + +.foo +{"notfoo": true, "alsonotfoo": false} +null + +.["foo"] +{"foo": 42} +42 + +.[0] +[{"name":"JSON", "good":true}, {"name":"XML", "good":false}] +{"name":"JSON", "good":true} + +.[2] +[{"name":"JSON", "good":true}, {"name":"XML", "good":false}] +null + +.[-2] +[1,2,3] +2 + +{a:1, b:2} +.["a","b"] +1 +2 + +.[2:4] +["a","b","c","d","e"] +["c", "d"] + +.[2:4] +"abcdefghi" +"cd" + +.[:3] +["a","b","c","d","e"] +["a", "b", "c"] + +.[-2:] +["a","b","c","d","e"] +["d", "e"] + +.[:range(1; length+1)] +[1,2,3] +[1] +[1,2] +[1,2,3] + +.foo? +{"foo": 42, "bar": "less interesting data"} +42 + +.foo? +{"notfoo": true, "alsonotfoo": false} +null + +.["foo"]? +{"foo": 42} +42 + +[.foo?] +[1,2] +[] + +.a + 1 +{"a": 7} +8 + +.a + .b +{"a": [1,2], "b": [3,4]} +[1,2,3,4] + +.a + null +{"a": 1} +1 + +.a + 1 +{} +1 + +{a: 1} + {b: 2} + {c: 3} + {a: 42} +null +{"a": 42, "b": 2, "c": 3} + +4 - .a +{"a":3} +1 + +. - ["xml", "yaml"] +["xml", "yaml", "json"] +["json"] + +10 / . * 3 +5 +6 + +. / ", " +"a, b,c,d, e" +["a","b,c,d","e"] + +{"k": {"a": 1, "b": 2}} * {"k": {"a": 0,"c": 3}} +null +{"k": {"a": 0, "b": 2, "c": 3}} + +.[] | (1 / .)? +[1,0,-1] +1 +-1 + +. == false +null +false + +. == {"b": {"d": (4 + 1e-20), "c": 3}, "a":1} +{"a":1, "b": {"c": 3, "d": 4}} +true + +.[] == 1 +[1, 1.0, "1", "banana"] +true +true +false +false + +. < 5 +2 +true + +[1,3] > [1,2] +null +true + +"jq" > false +null +true + +if . == 0 then "zero" elif . == 1 then "one" else "many" end +2 +"many" + +.[] | if . then ., .+1 else . end +[false, 1, null] +false +1 +2 +null + +if range(0;4) % 2 == 0 then "even" else "odd" end +null +"even" +"odd" +"even" +"odd" + +42 and "a string" +null +true + +(true, false) or false +null +true +false + +(true, true) and (true, false) +null +true +false +true +false + +[true, false | not] +null +[false, true] + +empty // 42 +null +42 + +.foo // 42 +{"foo": 19} +19 + +.foo // 42 +{} +42 + +(false, null, 1) // 42 +null +1 + +(false, null, 1) | . // 42 +null +42 +42 +1 + +try .a catch ". is not an object" +true +". is not an object" + +[.[]|try .a] +[{}, true, {"a":1}] +[null, 1] + +try error("some exception") catch . +true +"some exception" + +[.[] | .a?] +[{}, true, {"a":1}] +[null, 1] + +[.[] | tonumber?] +["1", "invalid", "3", 4] +[1, 3, 4] + +.bar as $x | .foo | . + $x +{"foo":10, "bar":200} +210 + +. as $i|[(.*2|. as $i| $i), $i] +5 +[10,5] + +. as [$a, $b, {c: $c}] | $a + $b + $c +[2, 3, {"c": 4, "d": 5}] +9 + +.[] as [$a, $b] | {a: $a, b: $b} +[[0], [0, 1], [2, 1, 0]] +{"a":0,"b":null} +{"a":0,"b":1} +{"a":2,"b":1} + +foreach .[] as {("a", "b"): $x} ([]; . + [$x]) +[{"a": 1, "b": 2}, {"a": 3, "b": 4}] +[1] +[1,2] +[1,2,3] +[1,2,3,4] + +.[] as {$a, $b, c: {$d, $e}} ?// {$a, $b, c: [{$d, $e}]} | {$a, $b, $d, $e} +[{"a": 1, "b": 2, "c": {"d": 3, "e": 4}}, {"a": 1, "b": 2, "c": [{"d": 3, "e": 4}]}] +{"a":1,"b":2,"d":3,"e":4} +{"a":1,"b":2,"d":3,"e":4} + +.[] as {$a, $b, c: {$d}} ?// {$a, $b, c: [{$e}]} | {$a, $b, $d, $e} +[{"a": 1, "b": 2, "c": {"d": 3, "e": 4}}, {"a": 1, "b": 2, "c": [{"d": 3, "e": 4}]}] +{"a":1,"b":2,"d":3,"e":null} +{"a":1,"b":2,"d":null,"e":4} + +.[] as [$a] ?// [$b] | if $a != null then error("err: \($a)") else {$a,$b} end +[[3]] +{"a":null,"b":3} + +reduce .[] as $item (0; . + $item) +[1,2,3,4,5] +15 + +reduce .[] as [$i,$j] (0; . + $i * $j) +[[1,2],[3,4],[5,6]] +44 + +reduce .[] as {$x,$y} (null; .x += $x | .y += [$y]) +[{"x":"a","y":1},{"x":"b","y":2},{"x":"c","y":3}] +{"x":"abc","y":[1,2,3]} + +foreach .[] as $item (0; . + $item) +[1,2,3,4,5] +1 +3 +6 +10 +15 + +foreach .[] as $item (0; . + $item; [$item, . * 2]) +[1,2,3,4,5] +[1,2] +[2,6] +[3,12] +[4,20] +[5,30] + +foreach .[] as $item (0; . + 1; {index: ., $item}) +["foo", "bar", "baz"] +{"index":1,"item":"foo"} +{"index":2,"item":"bar"} +{"index":3,"item":"baz"} + +def addvalue(f): . + [f]; map(addvalue(.[0])) +[[1,2],[10,20]] +[[1,2,1], [10,20,10]] + +def addvalue(f): f as $x | map(. + $x); addvalue(.[0]) +[[1,2],[10,20]] +[[1,2,1,2], [10,20,1,2]] + +def range(init; upto; by): def _range: if (by > 0 and . < upto) or (by < 0 and . > upto) then ., ((.+by)|_range) else . end; if by == 0 then init else init|_range end | select((by > 0 and . < upto) or (by < 0 and . > upto)); range(0; 10; 3) +null +0 +3 +6 +9 + +def while(cond; update): def _while: if cond then ., (update | _while) else empty end; _while; [while(.<100; .*2)] +1 +[1,2,4,8,16,32,64] + +.a = .b +{"a": {"b": 10}, "b": 20} +{"a":20,"b":20} + +.a |= .b +{"a": {"b": 10}, "b": 20} +{"a":10,"b":20} + +.foo += 1 +{"foo": 42} +{"foo": 43} + +(..|select(type=="boolean")) |= if . then 1 else 0 end +[true,false,[5,true,[true,[false]],false]] +[1,0,[5,1,[1,[0]],0]] + +(.a, .b) = range(3) +{} +{"a":0,"b":0} +{"a":1,"b":1} +{"a":2,"b":2} + +(.a, .b) |= range(3) +{} +{"a":0,"b":0} + +1, empty, 2 +null +1 +2 + +[1,2,empty,3] +null +[1,2,3] + +try error catch . +"error message" +"error message" + +try error("invalid value: \(.)") catch . +42 +"invalid value: 42" + +.[] | length +[[1,2], "string", {"a":2}, null, -5] +2 +6 +1 +0 +5 + +keys +{"abc": 1, "abcd": 2, "Foo": 3} +["Foo", "abc", "abcd"] + +keys +[42,3,35] +[0,1,2] + +map(.+1) +[1,2,3] +[2,3,4] + +map_values(.+1) +{"a": 1, "b": 2, "c": 3} +{"a": 2, "b": 3, "c": 4} + +map(., .) +[1,2] +[1,1,2,2] + +map_values(. // empty) +{"a": null, "b": true, "c": false} +{"b":true} + +to_entries +{"a": 1, "b": 2} +[{"key":"a", "value":1}, {"key":"b", "value":2}] + +from_entries +[{"key":"a", "value":1}, {"key":"b", "value":2}] +{"a": 1, "b": 2} + +with_entries(.key |= "KEY_" + .) +{"a": 1, "b": 2} +{"KEY_a": 1, "KEY_b": 2} + +map(select(. >= 2)) +[1,5,3,0,7] +[5,3,7] + +.[] | select(.id == "second") +[{"id": "first", "val": 1}, {"id": "second", "val": 2}] +{"id": "second", "val": 2} + +map(type) +[0, false, [], {}, null, "hello"] +["number", "boolean", "array", "object", "null", "string"] + +.[]|numbers +[[],{},1,"foo",null,true,false] +1 + +contains("bar") +"foobar" +true + +contains(["baz", "bar"]) +["foobar", "foobaz", "blarp"] +true + +contains(["bazzzzz", "bar"]) +["foobar", "foobaz", "blarp"] +false + +contains({foo: 12, bar: [{barp: 12}]}) +{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]} +true + +contains({foo: 12, bar: [{barp: 15}]}) +{"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]} +false + +indices(", ") +"a,b, cd, efg, hijk" +[3,7,12] + +indices(1) +[0,1,2,1,3,1,4] +[1,3,5] + +indices([1,2]) +[0,1,2,3,1,4,2,5,1,2,6,7] +[1,8] + +index(", ") +"a,b, cd, efg, hijk" +3 + +index(1) +[0,1,2,1,3,1,4] +1 + +index([1,2]) +[0,1,2,3,1,4,2,5,1,2,6,7] +1 + +rindex(", ") +"a,b, cd, efg, hijk" +12 + +rindex(1) +[0,1,2,1,3,1,4] +5 + +rindex([1,2]) +[0,1,2,3,1,4,2,5,1,2,6,7] +8 + +inside("foobar") +"bar" +true + +inside(["foobar", "foobaz", "blarp"]) +["baz", "bar"] +true + +inside(["foobar", "foobaz", "blarp"]) +["bazzzzz", "bar"] +false + +inside({"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}) +{"foo": 12, "bar": [{"barp": 12}]} +true + +inside({"foo": 12, "bar":[1,2,{"barp":12, "blip":13}]}) +{"foo": 12, "bar": [{"barp": 15}]} +false + +map(has("foo")) +[{"foo": 42}, {}] +[true, false] + +map(has(2)) +[[0,1], ["a","b","c"]] +[false, true] + +.[] | in({"foo": 42}) +["foo", "bar"] +true +false + +map(in([0,1])) +[2, 0] +[false, true] + +bsearch(0) +[0,1] +0 + +bsearch(0) +[1,2,3] +-1 + +bsearch(4) as $ix | if $ix < 0 then .[-(1+$ix)] = 4 else . end +[1,2,3] +[1,2,3,4] + +path(.a[0].b) +null +["a",0,"b"] + +[path(..)] +{"a":[{"b":1}]} +[[],["a"],["a",0],["a",0,"b"]] + +del(.foo) +{"foo": 42, "bar": 9001, "baz": 42} +{"bar": 9001, "baz": 42} + +del(.[1, 2]) +["foo", "bar", "baz"] +["foo"] + +pick(.a, .b.c, .x) +{"a": 1, "b": {"c": 2, "d": 3}, "e": 4} +{"a":1,"b":{"c":2},"x":null} + +pick(.[2], .[0], .[0]) +[1,2,3,4] +[1,null,3] + +[paths] +[1,[[],{"a":2}]] +[[0],[1],[1,0],[1,1],[1,1,"a"]] + +[paths(type == "number")] +[1,[[],{"a":2}]] +[[0],[1,1,"a"]] + +getpath(["a","b"]) +null +null + +[getpath(["a","b"], ["a","c"])] +{"a":{"b":0, "c":1}} +[0, 1] + +setpath(["a","b"]; 1) +null +{"a": {"b": 1}} + +setpath(["a","b"]; 1) +{"a":{"b":0}} +{"a": {"b": 1}} + +setpath([0,"a"]; 1) +null +[{"a":1}] + +delpaths([["a","b"]]) +{"a":{"b":1},"x":{"y":2}} +{"a":{},"x":{"y":2}} + +add +["a","b","c"] +"abc" + +add +[1, 2, 3] +6 + +add +[] +null + +add(.[].a) +[{"a":3}, {"a":5}, {"b":6}] +8 + +any +[true, false] +true + +any +[false, false] +false + +any +[] +false + +all +[true, false] +false + +all +[true, true] +true + +all +[] +true + +map(abs) +[-10, -1.1, -1e-1] +[10,1.1,1e-1] + +floor +3.14159 +3 + +sqrt +9 +3 + +.[] | (infinite * .) < 0 +[-1, 1] +true +false + +infinite, nan | type +null +"number" +"number" + +sort +[8,3,null,6] +[null,3,6,8] + +sort_by(.foo) +[{"foo":4, "bar":10}, {"foo":3, "bar":10}, {"foo":2, "bar":1}] +[{"foo":2, "bar":1}, {"foo":3, "bar":10}, {"foo":4, "bar":10}] + +sort_by(.foo, .bar) +[{"foo":4, "bar":10}, {"foo":3, "bar":20}, {"foo":2, "bar":1}, {"foo":3, "bar":10}] +[{"foo":2, "bar":1}, {"foo":3, "bar":10}, {"foo":3, "bar":20}, {"foo":4, "bar":10}] + +group_by(.foo) +[{"foo":1, "bar":10}, {"foo":3, "bar":100}, {"foo":1, "bar":1}] +[[{"foo":1, "bar":10}, {"foo":1, "bar":1}], [{"foo":3, "bar":100}]] + +min +[5,4,2,7] +2 + +max_by(.foo) +[{"foo":1, "bar":14}, {"foo":2, "bar":3}] +{"foo":2, "bar":3} + +unique +[1,2,5,3,5,3,1,3] +[1,2,3,5] + +unique_by(.foo) +[{"foo": 1, "bar": 2}, {"foo": 1, "bar": 3}, {"foo": 4, "bar": 5}] +[{"foo": 1, "bar": 2}, {"foo": 4, "bar": 5}] + +unique_by(length) +["chunky", "bacon", "kitten", "cicada", "asparagus"] +["bacon", "chunky", "asparagus"] + +reverse +[1,2,3,4] +[4,3,2,1] + +combinations +[[1,2], [3, 4]] +[1, 3] +[1, 4] +[2, 3] +[2, 4] + +combinations(2) +[0, 1] +[0, 0] +[0, 1] +[1, 0] +[1, 1] + +transpose +[[1], [2,3]] +[[1,2],[null,3]] + +flatten +[1, [2], [[3]]] +[1, 2, 3] + +flatten(1) +[1, [2], [[3]]] +[1, 2, [3]] + +flatten +[[]] +[] + +flatten +[{"foo": "bar"}, [{"foo": "baz"}]] +[{"foo": "bar"}, {"foo": "baz"}] + +utf8bytelength +"\u03bc" +2 + +[.[]|startswith("foo")] +["fo", "foo", "barfoo", "foobar", "barfoob"] +[false, true, false, true, false] + +[.[]|endswith("foo")] +["foobar", "barfoo"] +[false, true] + +[.[]|ltrimstr("foo")] +["fo", "foo", "barfoo", "foobar", "afoo"] +["fo","","barfoo","bar","afoo"] + +[.[]|rtrimstr("foo")] +["fo", "foo", "barfoo", "foobar", "foob"] +["fo","","bar","foobar","foob"] + +trim, ltrim, rtrim +" abc " +"abc" +"abc " +" abc" + +explode +"foobar" +[102,111,111,98,97,114] + +implode +[65, 66, 67] +"ABC" + +join(", ") +["a","b,c,d","e"] +"a, b,c,d, e" + +join(" ") +["a",1,2.3,true,null,false] +"a 1 2.3 true false" + +ascii_upcase +"useful but not for é" +"USEFUL BUT NOT FOR é" + +[repeat(.*2, error)?] +1 +[2] + +range(2; 4) +null +2 +3 + +[range(2; 4)] +null +[2,3] + +[range(4)] +null +[0,1,2,3] + +[range(0; 10; 3)] +null +[0,3,6,9] + +[range(0; 10; -1)] +null +[] + +[range(0; -5; -1)] +null +[0,-1,-2,-3,-4] + +[while(.<100; .*2)] +1 +[1,2,4,8,16,32,64] + +[.,1]|until(.[0] < 1; [.[0] - 1, .[1] * .[0]])|.[1] +4 +24 + +recurse(.foo[]) +{"foo":[{"foo": []}, {"foo":[{"foo":[]}]}]} +{"foo":[{"foo":[]},{"foo":[{"foo":[]}]}]} +{"foo":[]} +{"foo":[{"foo":[]}]} +{"foo":[]} + +recurse +{"a":0,"b":[1]} +{"a":0,"b":[1]} +0 +[1] +1 + +recurse(. * .; . < 20) +2 +2 +4 +16 + +walk(if type == "array" then sort else . end) +[[4, 1, 7], [8, 5, 2], [3, 6, 9]] +[[1,4,7],[2,5,8],[3,6,9]] + +isempty(empty) +null +true + +isempty(.[]) +[] +true + +isempty(.[]) +[1,2,3] +false + +[limit(3;.[])] +[0,1,2,3,4,5,6,7,8,9] +[0,1,2] + +[skip(3; .[])] +[0,1,2,3,4,5,6,7,8,9] +[3,4,5,6,7,8,9] + +[first(range(.)), last(range(.)), nth(5; range(.))] +10 +[0,9,5] + +[first(empty), last(empty), nth(5; empty)] +null +[] + +[range(.)]|[first, last, nth(5)] +10 +[0,9,5] + +[.[]|tostring] +[1, "foo", ["foo"]] +["1","foo","[\"foo\"]"] + +[.[]|tojson] +[1, "foo", ["foo"]] +["1","\"foo\"","[\"foo\"]"] + +[.[]|tojson|fromjson] +[1, "foo", ["foo"]] +[1,"foo",["foo"]] + +.[] | tostring +[1, "1", [1]] +"1" +"1" +"[1]" + +.[] | tonumber +[1, "1"] +1 +1 + +fromdate +"2015-03-05T23:51:47Z" +1425599507 + +strptime("%Y-%m-%dT%H:%M:%SZ") +"2015-03-05T23:51:47Z" +[2015,2,5,23,51,47,4,63] + +strptime("%Y-%m-%dT%H:%M:%SZ")|mktime +"2015-03-05T23:51:47Z" +1425599507 + +$ENV.PAGER +null +"less" + +env.PAGER +null +"less" + +truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]]) +1 +[[0],2] +[[0]] + +fromstream(1|truncate_stream([[0],1],[[1,0],2],[[1,0]],[[1]])) +null +[2] + +. as $dot|fromstream($dot|tostream)|.==$dot +[0,[1,{"a":1},{"b":2}]] +true + +try error("\($__loc__)") catch . +null +"{\"file\":\"\",\"line\":1}" + +[., tojson] | . == if have_decnum then [12345678909876543212345,"12345678909876543212345"] else [12345678909876543000000,"12345678909876543000000"] end +12345678909876543212345 +true + +map([., . == 1]) | tojson | . == if have_decnum then "[[1,true],[1.000,true],[1.0,true],[1.00,true]]" else "[[1,true],[1,true],[1,true],[1,true]]" end +[1, 1.000, 1.0, 100e-2] +true + +. as $big | [$big, $big + 1] | map(. > 10000000000000000000000000000000) | . == if have_decnum then [true, false] else [false, false] end +10000000000000000000000000000001 +true +