17370 lines
211 KiB
Groff
17370 lines
211 KiB
Groff
'\" t
|
|
.\" Automatically generated by Pandoc 2.14.2
|
|
.\"
|
|
.TH "YQ" "1" "" "" "yq (https://github.com/mikefarah/yq/) version v4.45.4"
|
|
.hy
|
|
.SH NAME
|
|
.PP
|
|
\f[I]yq\f[R] is a portable command-line data file processor
|
|
.SH SYNOPSIS
|
|
.PP
|
|
yq [eval/eval-all] [expression] files..
|
|
.PP
|
|
eval/e - (default) Apply the expression to each document in each yaml
|
|
file in sequence
|
|
.PP
|
|
eval-all/ea - Loads all yaml documents of all yaml files and runs
|
|
expression once
|
|
.SH DESCRIPTION
|
|
.PP
|
|
a lightweight and portable command-line data file processor.
|
|
\f[C]yq\f[R] uses jq (https://github.com/stedolan/jq) like syntax but
|
|
works with yaml, json, xml, csv, properties and TOML files.
|
|
It doesn\[cq]t yet support everything \f[C]jq\f[R] does - but it does
|
|
support the most common operations and functions, and more is being
|
|
added continuously.
|
|
.PP
|
|
This documentation is also available at https://mikefarah.gitbook.io/yq/
|
|
# QUICK GUIDE
|
|
.SS Read a value:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b[0].c\[aq] file.yaml
|
|
\f[R]
|
|
.fi
|
|
.SS Pipe from STDIN:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat file.yaml | yq \[aq].a.b[0].c\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Update a yaml file, in place
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -i \[aq].a.b[0].c = \[dq]cool\[dq]\[aq] file.yaml
|
|
\f[R]
|
|
.fi
|
|
.SS Update using environment variables
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
NAME=mike yq -i \[aq].a.b[0].c = strenv(NAME)\[aq] file.yaml
|
|
\f[R]
|
|
.fi
|
|
.SS Merge multiple files
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq ea \[aq]. as $item ireduce ({}; . * $item )\[aq] path/to/*.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Note the use of \f[C]ea\f[R] to evaluate all files at once (instead of
|
|
in sequence.)
|
|
.SS Multiple updates to a yaml file
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -i \[aq]
|
|
.a.b[0].c = \[dq]cool\[dq] |
|
|
.x.y.z = \[dq]foobar\[dq] |
|
|
.person.name = strenv(NAME)
|
|
\[aq] file.yaml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
See the documentation (https://mikefarah.gitbook.io/yq/) for more.
|
|
.SH KNOWN ISSUES / MISSING FEATURES
|
|
.IP \[bu] 2
|
|
\f[C]yq\f[R] attempts to preserve comment positions and whitespace as
|
|
much as possible, but it does not handle all scenarios (see
|
|
https://github.com/go-yaml/yaml/tree/v3 for details)
|
|
.IP \[bu] 2
|
|
Powershell has its own\&...opinions:
|
|
https://mikefarah.gitbook.io/yq/usage/tips-and-tricks#quotes-in-windows-powershell
|
|
.SH BUGS / ISSUES / FEATURE REQUESTS
|
|
.PP
|
|
Please visit the GitHub page https://github.com/mikefarah/yq/.
|
|
.SH HOW IT WORKS
|
|
.PP
|
|
In \f[C]yq\f[R] expressions are made up of operators and pipes.
|
|
A context of nodes is passed through the expression and each operation
|
|
takes the context as input and returns a new context as output.
|
|
That output is piped in as input for the next operation in the
|
|
expression.
|
|
To begin with, the context is set to the first yaml document of the
|
|
first yaml file (if processing in sequence using eval).
|
|
.PP
|
|
Lets look at a couple of examples.
|
|
.SS Simple assignment example
|
|
.PP
|
|
Given a document like:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
with an expression:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\&.a = .b
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Like math expressions - operator precedence is important.
|
|
.PP
|
|
The \f[C]=\f[R] operator takes two arguments, a \f[C]lhs\f[R]
|
|
expression, which in this case is \f[C].a\f[R] and \f[C]rhs\f[R]
|
|
expression which is \f[C].b\f[R].
|
|
.PP
|
|
It pipes the current, lets call it `root' context through the
|
|
\f[C]lhs\f[R] expression of \f[C].a\f[R] to return the node
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Side note: this node holds not only its value `cat', but comments and
|
|
metadata too, including path and parent information.
|
|
.PP
|
|
The \f[C]=\f[R] operator then pipes the `root' context through the
|
|
\f[C]rhs\f[R] expression of \f[C].b\f[R] to return the node
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Both sides have now been evaluated, so now the operator copies across
|
|
the value from the RHS (\f[C].b\f[R]) to the LHS (\f[C].a\f[R]), and it
|
|
returns the now updated context:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: dog
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Complex assignment, operator precedence rules
|
|
.PP
|
|
Just like math expressions - \f[C]yq\f[R] expressions have an order of
|
|
precedence.
|
|
The pipe \f[C]|\f[R] operator has a low order of precedence, so
|
|
operators with higher precedence will get evaluated first.
|
|
.PP
|
|
Most of the time, this is intuitively what you\[cq]d want, for instance
|
|
\f[C].a = \[dq]cat\[dq] | .b = \[dq]dog\[dq]\f[R] is effectively:
|
|
\f[C](.a = \[dq]cat\[dq]) | (.b = \[dq]dog\[dq])\f[R].
|
|
.PP
|
|
However, this is not always the case, particularly if you have a complex
|
|
LHS or RHS expression, for instance if you want to select particular
|
|
nodes to update.
|
|
.PP
|
|
Lets say you had:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: bob
|
|
fruit: apple
|
|
- name: sally
|
|
fruit: orange
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Lets say you wanted to update the \f[C]sally\f[R] entry to have fruit:
|
|
`mango'.
|
|
The \f[I]incorrect\f[R] way to do that is:
|
|
\f[C].[] | select(.name == \[dq]sally\[dq]) | .fruit = \[dq]mango\[dq]\f[R].
|
|
.PP
|
|
Because \f[C]|\f[R] has a low operator precedence, this will be
|
|
evaluated (\f[I]incorrectly\f[R]) as :
|
|
\f[C](.[]) | (select(.name == \[dq]sally\[dq])) | (.fruit = \[dq]mango\[dq])\f[R].
|
|
What you\[cq]ll see is only the updated segment returned:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: sally
|
|
fruit: mango
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
To properly update this yaml, you will need to use brackets (think
|
|
BODMAS from maths) and wrap the entire LHS:
|
|
\f[C](.[] | select(.name == \[dq]sally\[dq]) | .fruit) = \[dq]mango\[dq]\f[R]
|
|
.PP
|
|
Now that entire LHS expression is passed to the `assign' (\f[C]=\f[R])
|
|
operator, and the yaml is correctly updated and returned:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: bob
|
|
fruit: apple
|
|
- name: sally
|
|
fruit: mango
|
|
\f[R]
|
|
.fi
|
|
.SS Relative update (e.g.\ \f[C]|=\f[R])
|
|
.PP
|
|
There is another form of the \f[C]=\f[R] operator which we call the
|
|
relative form.
|
|
It\[cq]s very similar to \f[C]=\f[R] but with one key difference when
|
|
evaluating the RHS expression.
|
|
.PP
|
|
In the plain form, we pass in the `root' level context to the RHS
|
|
expression.
|
|
In relative form, we pass in \f[I]each result of the LHS\f[R] to the RHS
|
|
expression.
|
|
Let\[cq]s go through an example.
|
|
.PP
|
|
Given a document like:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
with an expression:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\&.a |= . + 1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Similar to the \f[C]=\f[R] operator, \f[C]|=\f[R] takes two operands,
|
|
the LHS and RHS.
|
|
.PP
|
|
It pipes the current context (the whole document) through the LHS
|
|
expression of \f[C].a\f[R] to get the node value:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Now it pipes \f[I]that LHS context\f[R] into the RHS expression
|
|
\f[C]. + 1\f[R] (whereas in the \f[C]=\f[R] plain form it piped the
|
|
original document context into the RHS) to yield:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
The assignment operator then copies across the value from the RHS to the
|
|
value on the LHS, and it returns the now updated `root' context:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2
|
|
b: thing
|
|
\f[R]
|
|
.fi
|
|
.SH Add
|
|
.PP
|
|
Add behaves differently according to the type of the LHS: * arrays:
|
|
concatenate * number scalars: arithmetic addition * string scalars:
|
|
concatenate * maps: shallow merge (use the multiply operator
|
|
(\f[C]*\f[R]) to deeply merge)
|
|
.PP
|
|
Use \f[C]+=\f[R] as a relative append assign for things like increment.
|
|
Note that \f[C].a += .x\f[R] is equivalent to running
|
|
\f[C].a = .a + .x\f[R].
|
|
.SS Concatenate arrays
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- 1
|
|
- 2
|
|
b:
|
|
- 3
|
|
- 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a + .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
- 4
|
|
\f[R]
|
|
.fi
|
|
.SS Concatenate to existing array
|
|
.PP
|
|
Note that the styling of \f[C]a\f[R] is kept.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: [1,2]
|
|
b:
|
|
- 3
|
|
- 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a += .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: [1, 2, 3, 4]
|
|
b:
|
|
- 3
|
|
- 4
|
|
\f[R]
|
|
.fi
|
|
.SS Concatenate null to array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- 1
|
|
- 2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a + null\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
\f[R]
|
|
.fi
|
|
.SS Append to existing array
|
|
.PP
|
|
Note that the styling is copied from existing array elements
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: [\[aq]dog\[aq]]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a += \[dq]cat\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: [\[aq]dog\[aq], \[aq]cat\[aq]]
|
|
\f[R]
|
|
.fi
|
|
.SS Prepend to existing array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = [\[dq]cat\[dq]] + .a\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.SS Add new object to array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- dog: woof
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a + {\[dq]cat\[dq]: \[dq]meow\[dq]}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- dog: woof
|
|
- cat: meow
|
|
\f[R]
|
|
.fi
|
|
.SS Relative append
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
a1:
|
|
b:
|
|
- cat
|
|
a2:
|
|
b:
|
|
- dog
|
|
a3: {}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a[].b += [\[dq]mouse\[dq]]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
a1:
|
|
b:
|
|
- cat
|
|
- mouse
|
|
a2:
|
|
b:
|
|
- dog
|
|
- mouse
|
|
a3:
|
|
b:
|
|
- mouse
|
|
\f[R]
|
|
.fi
|
|
.SS String concatenation
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: meow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a += .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: catmeow
|
|
b: meow
|
|
\f[R]
|
|
.fi
|
|
.SS Number addition - float
|
|
.PP
|
|
If the lhs or rhs are floats then the expression will be calculated with
|
|
floats.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 3
|
|
b: 4.9
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a + .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 7.9
|
|
b: 4.9
|
|
\f[R]
|
|
.fi
|
|
.SS Number addition - int
|
|
.PP
|
|
If both the lhs and rhs are ints then the expression will be calculated
|
|
with ints.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 3
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a + .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 7
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.SS Increment numbers
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 3
|
|
b: 5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] += 1\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 4
|
|
b: 6
|
|
\f[R]
|
|
.fi
|
|
.SS Date addition
|
|
.PP
|
|
You can add durations to dates.
|
|
Assumes RFC3339 date time format, see date-time
|
|
operators (https://mikefarah.gitbook.io/yq/operators/date-time-operators)
|
|
for more information.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T00:00:00Z
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a += \[dq]3h10m\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T03:10:00Z
|
|
\f[R]
|
|
.fi
|
|
.SS Date addition - custom format
|
|
.PP
|
|
You can add durations to dates.
|
|
See date-time
|
|
operators (https://mikefarah.gitbook.io/yq/operators/date-time-operators)
|
|
for more information.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:59AM GMT
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_dtf(\[dq]Monday, 02-Jan-06 at 3:04PM MST\[dq], .a += \[dq]3h1m\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 6:00AM GMT
|
|
\f[R]
|
|
.fi
|
|
.SS Add to null
|
|
.PP
|
|
Adding to null simply returns the rhs
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]null + \[dq]cat\[dq]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.SS Add maps to shallow merge
|
|
.PP
|
|
Adding objects together shallow merges them.
|
|
Use \f[C]*\f[R] to deeply merge.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
thing:
|
|
name: Astuff
|
|
value: x
|
|
a1: cool
|
|
b:
|
|
thing:
|
|
name: Bstuff
|
|
legs: 3
|
|
b1: neat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a += .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
thing:
|
|
name: Bstuff
|
|
legs: 3
|
|
a1: cool
|
|
b1: neat
|
|
b:
|
|
thing:
|
|
name: Bstuff
|
|
legs: 3
|
|
b1: neat
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types: that are really strings
|
|
.PP
|
|
When custom tags are encountered, yq will try to decode the underlying
|
|
type.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse cat
|
|
b: !goat _meow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a += .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse cat_meow
|
|
b: !goat _meow
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types: that are really numbers
|
|
.PP
|
|
When custom tags are encountered, yq will try to decode the underlying
|
|
type.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse 1.2
|
|
b: !goat 2.3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a += .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse 3.5
|
|
b: !goat 2.3
|
|
\f[R]
|
|
.fi
|
|
.SH Alternative (Default value)
|
|
.PP
|
|
This operator is used to provide alternative (or default) values when a
|
|
particular expression is either null or false.
|
|
.SS LHS is defined
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: bridge
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a // \[dq]hello\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bridge
|
|
\f[R]
|
|
.fi
|
|
.SS LHS is not defined
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a // \[dq]hello\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
hello
|
|
\f[R]
|
|
.fi
|
|
.SS LHS is null
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[ti]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a // \[dq]hello\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
hello
|
|
\f[R]
|
|
.fi
|
|
.SS LHS is false
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: false
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a // \[dq]hello\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
hello
|
|
\f[R]
|
|
.fi
|
|
.SS RHS is an expression
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: false
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a // .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.SS Update or create - entity exists
|
|
.PP
|
|
This initialises \f[C]a\f[R] if it\[cq]s not present
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.a // (.a = 0)) += 1\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2
|
|
\f[R]
|
|
.fi
|
|
.SS Update or create - entity does not exist
|
|
.PP
|
|
This initialises \f[C]a\f[R] if it\[cq]s not present
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: camel
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.a // (.a = 0)) += 1\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: camel
|
|
a: 1
|
|
\f[R]
|
|
.fi
|
|
.SH Anchor and Alias Operators
|
|
.PP
|
|
Use the \f[C]alias\f[R] and \f[C]anchor\f[R] operators to read and write
|
|
yaml aliases and anchors.
|
|
The \f[C]explode\f[R] operator normalises a yaml file (dereference (or
|
|
expands) aliases and remove anchor names).
|
|
.PP
|
|
\f[C]yq\f[R] supports merge aliases (like \f[C]<<: *blah\f[R]) however
|
|
this is no longer in the standard yaml spec (1.2) and so \f[C]yq\f[R]
|
|
will automatically add the \f[C]!!merge\f[R] tag to these nodes as it is
|
|
effectively a custom tag.
|
|
.SS Merge one map
|
|
.PP
|
|
see https://yaml.org/type/merge.html
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- &CENTER
|
|
x: 1
|
|
y: 2
|
|
- &LEFT
|
|
x: 0
|
|
y: 2
|
|
- &BIG
|
|
r: 10
|
|
- &SMALL
|
|
r: 1
|
|
- !!merge <<: *CENTER
|
|
r: 10
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[4] | explode(.)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
x: 1
|
|
y: 2
|
|
r: 10
|
|
\f[R]
|
|
.fi
|
|
.SS Merge multiple maps
|
|
.PP
|
|
see https://yaml.org/type/merge.html
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- &CENTER
|
|
x: 1
|
|
y: 2
|
|
- &LEFT
|
|
x: 0
|
|
y: 2
|
|
- &BIG
|
|
r: 10
|
|
- &SMALL
|
|
r: 1
|
|
- !!merge <<:
|
|
- *CENTER
|
|
- *BIG
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[4] | explode(.)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
r: 10
|
|
x: 1
|
|
y: 2
|
|
\f[R]
|
|
.fi
|
|
.SS Override
|
|
.PP
|
|
see https://yaml.org/type/merge.html
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- &CENTER
|
|
x: 1
|
|
y: 2
|
|
- &LEFT
|
|
x: 0
|
|
y: 2
|
|
- &BIG
|
|
r: 10
|
|
- &SMALL
|
|
r: 1
|
|
- !!merge <<:
|
|
- *BIG
|
|
- *LEFT
|
|
- *SMALL
|
|
x: 1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[4] | explode(.)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
r: 10
|
|
x: 1
|
|
y: 2
|
|
\f[R]
|
|
.fi
|
|
.SS Get anchor
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &billyBob cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | anchor\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
billyBob
|
|
\f[R]
|
|
.fi
|
|
.SS Set anchor
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a anchor = \[dq]foobar\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &foobar cat
|
|
\f[R]
|
|
.fi
|
|
.SS Set anchor relatively using assign-update
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a anchor |= .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &cat
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Get alias
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: &billyBob meow
|
|
a: *billyBob
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | alias\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
billyBob
|
|
\f[R]
|
|
.fi
|
|
.SS Set alias
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: &meow purr
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a alias = \[dq]meow\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: &meow purr
|
|
a: *meow
|
|
\f[R]
|
|
.fi
|
|
.SS Set alias to blank does nothing
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: &meow purr
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a alias = \[dq]\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: &meow purr
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Set alias relatively using assign-update
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: &meow purr
|
|
a:
|
|
f: meow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a alias |= .f\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: &meow purr
|
|
a: *meow
|
|
\f[R]
|
|
.fi
|
|
.SS Explode alias and anchor
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
f:
|
|
a: &a cat
|
|
b: *a
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]explode(.f)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
f:
|
|
a: cat
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Explode with no aliases or anchors
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: mike
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]explode(.a)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: mike
|
|
\f[R]
|
|
.fi
|
|
.SS Explode with alias keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
f:
|
|
a: &a cat
|
|
*a: b
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]explode(.f)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
f:
|
|
a: cat
|
|
cat: b
|
|
\f[R]
|
|
.fi
|
|
.SS Explode with merge anchors
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]explode(.)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo:
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar:
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: bar_b
|
|
thing: foo_thing
|
|
c: foobarList_c
|
|
a: foo_a
|
|
foobar:
|
|
c: foo_c
|
|
a: foo_a
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.SS Dereference and update a field
|
|
.PP
|
|
Use explode with multiply to dereference an object
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
item_value: &item_value
|
|
value: true
|
|
thingOne:
|
|
name: item_1
|
|
!!merge <<: *item_value
|
|
thingTwo:
|
|
name: item_2
|
|
!!merge <<: *item_value
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].thingOne |= explode(.) * {\[dq]value\[dq]: false}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
item_value: &item_value
|
|
value: true
|
|
thingOne:
|
|
name: item_1
|
|
value: false
|
|
thingTwo:
|
|
name: item_2
|
|
!!merge <<: *item_value
|
|
\f[R]
|
|
.fi
|
|
.SH Array to Map
|
|
.PP
|
|
Use this operator to convert an array to..a map.
|
|
The indices are used as map keys, null values in the array are skipped
|
|
over.
|
|
.PP
|
|
Behind the scenes, this is implemented using reduce:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
(.[] | select(. != null) ) as $i ireduce({}; .[$i | key] = $i)
|
|
\f[R]
|
|
.fi
|
|
.SS Simple example
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool:
|
|
- null
|
|
- null
|
|
- hello
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].cool |= array_to_map\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool:
|
|
2: hello
|
|
\f[R]
|
|
.fi
|
|
.SH Assign (Update)
|
|
.PP
|
|
This operator is used to update node values.
|
|
It can be used in either the:
|
|
.SS plain form: \f[C]=\f[R]
|
|
.PP
|
|
Which will set the LHS node values equal to the RHS node values.
|
|
The RHS expression is run against the matching nodes in the pipeline.
|
|
.SS relative form: \f[C]|=\f[R]
|
|
.PP
|
|
This will do a similar thing to the plain form, but the RHS expression
|
|
is run with \f[I]each LHS node as context\f[R].
|
|
This is useful for updating values based on old values, e.g.\ increment.
|
|
.SS Flags
|
|
.IP \[bu] 2
|
|
\f[C]c\f[R] clobber custom tags
|
|
.SS Create yaml file
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq].a.b = \[dq]cat\[dq] | .x = \[dq]frog\[dq]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: cat
|
|
x: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Update node to be the child value
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
g: foof
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
g: foof
|
|
\f[R]
|
|
.fi
|
|
.SS Double elements in an array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] |= . * 2\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 2
|
|
- 4
|
|
- 6
|
|
\f[R]
|
|
.fi
|
|
.SS Update node from another file
|
|
.PP
|
|
Note this will also work when the second file is a scalar
|
|
(string/number)
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: apples
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
And another sample another.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: bob
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq eval-all \[aq]select(fileIndex==0).a = select(fileIndex==1) | select(fileIndex==0)\[aq] sample.yml another.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: bob
|
|
\f[R]
|
|
.fi
|
|
.SS Update node to be the sibling value
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: child
|
|
b: sibling
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: sibling
|
|
b: sibling
|
|
\f[R]
|
|
.fi
|
|
.SS Updated multiple paths
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: fieldA
|
|
b: fieldB
|
|
c: fieldC
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.a, .c) = \[dq]potato\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: potato
|
|
b: fieldB
|
|
c: potato
|
|
\f[R]
|
|
.fi
|
|
.SS Update string value
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b = \[dq]frog\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Update string value via |=
|
|
.PP
|
|
Note there is no difference between \f[C]=\f[R] and \f[C]|=\f[R] when
|
|
the RHS is a scalar
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b |= \[dq]frog\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Update deeply selected results
|
|
.PP
|
|
Note that the LHS is wrapped in brackets! This is to ensure we don\[cq]t
|
|
first filter out the yaml and then update the snippet.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: apple
|
|
c: cactus
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.a[] | select(. == \[dq]apple\[dq])) = \[dq]frog\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: frog
|
|
c: cactus
|
|
\f[R]
|
|
.fi
|
|
.SS Update array values
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- candy
|
|
- apple
|
|
- sandy
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.[] | select(. == \[dq]*andy\[dq])) = \[dq]bogs\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- bogs
|
|
- apple
|
|
- bogs
|
|
\f[R]
|
|
.fi
|
|
.SS Update empty object
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b |= \[dq]bogs\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: bogs
|
|
\f[R]
|
|
.fi
|
|
.SS Update node value that has an anchor
|
|
.PP
|
|
Anchor will remain
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &cool cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = \[dq]dog\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &cool dog
|
|
\f[R]
|
|
.fi
|
|
.SS Update empty object and array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b.[0] |= \[dq]bogs\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
- bogs
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types are maintained by default
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !cat meow
|
|
b: !dog woof
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !cat woof
|
|
b: !dog woof
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types: clobber
|
|
.PP
|
|
Use the \f[C]c\f[R] option to clobber custom tags
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !cat meow
|
|
b: !dog woof
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a =c .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !dog woof
|
|
b: !dog woof
|
|
\f[R]
|
|
.fi
|
|
.SH Boolean Operators
|
|
.PP
|
|
The \f[C]or\f[R] and \f[C]and\f[R] operators take two parameters and
|
|
return a boolean result.
|
|
.PP
|
|
\f[C]not\f[R] flips a boolean from true to false, or vice versa.
|
|
.PP
|
|
\f[C]any\f[R] will return \f[C]true\f[R] if there are any \f[C]true\f[R]
|
|
values in an array sequence, and \f[C]all\f[R] will return true if
|
|
\f[I]all\f[R] elements in an array are true.
|
|
.PP
|
|
\f[C]any_c(condition)\f[R] and \f[C]all_c(condition)\f[R] are like
|
|
\f[C]any\f[R] and \f[C]all\f[R] but they take a condition expression
|
|
that is used against each element to determine if it\[cq]s
|
|
\f[C]true\f[R].
|
|
Note: in \f[C]jq\f[R] you can simply pass a condition to \f[C]any\f[R]
|
|
or \f[C]all\f[R] and it simply works - \f[C]yq\f[R] isn\[cq]t that
|
|
clever..yet
|
|
.PP
|
|
These are most commonly used with the \f[C]select\f[R] operator to
|
|
filter particular nodes.
|
|
.SS Related Operators
|
|
.IP \[bu] 2
|
|
equals / not equals (\f[C]==\f[R], \f[C]!=\f[R]) operators
|
|
here (https://mikefarah.gitbook.io/yq/operators/equals)
|
|
.IP \[bu] 2
|
|
comparison (\f[C]>=\f[R], \f[C]<\f[R] etc) operators
|
|
here (https://mikefarah.gitbook.io/yq/operators/compare)
|
|
.IP \[bu] 2
|
|
select operator here (https://mikefarah.gitbook.io/yq/operators/select)
|
|
.SS \f[C]or\f[R] example
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]true or false\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS \[lq]yes\[rq] and \[lq]no\[rq] are strings
|
|
.PP
|
|
In the yaml 1.2 standard, support for yes/no as booleans was dropped -
|
|
they are now considered strings.
|
|
See `10.2.1.2. Boolean' in https://yaml.org/spec/1.2.2/
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- yes
|
|
- no
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | tag\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
!!str
|
|
!!str
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]and\f[R] example
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]true and false\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Matching nodes with select, equals and or
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: bird
|
|
b: dog
|
|
- a: frog
|
|
b: bird
|
|
- a: cat
|
|
b: fly
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][.[] | select(.a == \[dq]cat\[dq] or .b == \[dq]dog\[dq])]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: bird
|
|
b: dog
|
|
- a: cat
|
|
b: fly
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]any\f[R] returns true if any boolean in a given array is true
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- false
|
|
- true
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]any\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]any\f[R] returns false for an empty array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]any\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]any_c\f[R] returns true if any element in the array is true for the given condition.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- rad
|
|
- awesome
|
|
b:
|
|
- meh
|
|
- whatever
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] |= any_c(. == \[dq]awesome\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: true
|
|
b: false
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]all\f[R] returns true if all booleans in a given array are true
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- true
|
|
- true
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]all\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]all\f[R] returns true for an empty array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]all\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS \f[C]all_c\f[R] returns true if all elements in the array are true for the given condition.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- rad
|
|
- awesome
|
|
b:
|
|
- meh
|
|
- 12
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] |= all_c(tag == \[dq]!!str\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: true
|
|
b: false
|
|
\f[R]
|
|
.fi
|
|
.SS Not true is false
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]true | not\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Not false is true
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]false | not\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS String values considered to be true
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]cat\[dq] | not\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Empty string value considered to be true
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]\[dq] | not\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Numbers are considered to be true
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]1 | not\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Zero is considered to be true
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]0 | not\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Null is considered to be false
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[ti] | not\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SH Collect into Array
|
|
.PP
|
|
This creates an array using the expression between the square brackets.
|
|
.SS Collect empty
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq][]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[]
|
|
\f[R]
|
|
.fi
|
|
.SS Collect single
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq][\[dq]cat\[dq]]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
\f[R]
|
|
.fi
|
|
.SS Collect many
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][.a, .b]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.SH Column
|
|
.PP
|
|
Returns the column of the matching node.
|
|
Starts from 1, 0 indicates there was no column data.
|
|
.PP
|
|
Column is the number of characters that precede that node on the line it
|
|
starts.
|
|
.SS Returns column of \f[I]value\f[R] node
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: bob
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b | column\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
4
|
|
\f[R]
|
|
.fi
|
|
.SS Returns column of \f[I]key\f[R] node
|
|
.PP
|
|
Pipe through the key operator to get the column of the key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: bob
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b | key | column\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS First column is 1
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | key | column\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS No column data is 0
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]{\[dq]a\[dq]: \[dq]new entry\[dq]} | column\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0
|
|
\f[R]
|
|
.fi
|
|
.SH Comment Operators
|
|
.PP
|
|
Use these comment operators to set or retrieve comments.
|
|
Note that line comments on maps/arrays are actually set on the
|
|
\f[I]key\f[R] node as opposed to the \f[I]value\f[R] (map/array).
|
|
See below for examples.
|
|
.PP
|
|
Like the \f[C]=\f[R] and \f[C]|=\f[R] assign operators, the same syntax
|
|
applies when updating comments:
|
|
.SS plain form: \f[C]=\f[R]
|
|
.PP
|
|
This will set the LHS nodes\[cq] comments equal to the expression on the
|
|
RHS.
|
|
The RHS is run against the matching nodes in the pipeline
|
|
.SS relative form: \f[C]|=\f[R]
|
|
.PP
|
|
This is similar to the plain form, but it evaluates the RHS with
|
|
\f[I]each matching LHS node as context\f[R].
|
|
This is useful if you want to set the comments as a relative expression
|
|
of the node, for instance its value or path.
|
|
.SS Set line comment
|
|
.PP
|
|
Set the comment on the key node for more reliability (see below).
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a line_comment=\[dq]single\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat # single
|
|
\f[R]
|
|
.fi
|
|
.SS Set line comment of a maps/arrays
|
|
.PP
|
|
For maps and arrays, you need to set the line comment on the
|
|
\f[I]key\f[R] node.
|
|
This will also work for scalars.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: things
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.a | key) line_comment=\[dq]single\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: # single
|
|
b: things
|
|
\f[R]
|
|
.fi
|
|
.SS Use update assign to perform relative updates
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. line_comment |= .\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat # cat
|
|
b: dog # dog
|
|
\f[R]
|
|
.fi
|
|
.SS Where is the comment - map key example
|
|
.PP
|
|
The underlying yaml parser can assign comments in a document to
|
|
surprising nodes.
|
|
Use an expression like this to find where you comment is.
|
|
`p' indicates the path, `isKey' is if the node is a map key (as opposed
|
|
to a map value).
|
|
From this, you can see the `hello-world-comment' is actually on the
|
|
`hello' key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
hello: # hello-world-comment
|
|
message: world
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][... | {\[dq]p\[dq]: path | join(\[dq].\[dq]), \[dq]isKey\[dq]: is_key, \[dq]hc\[dq]: headComment, \[dq]lc\[dq]: lineComment, \[dq]fc\[dq]: footComment}]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- p: \[dq]\[dq]
|
|
isKey: false
|
|
hc: \[dq]\[dq]
|
|
lc: \[dq]\[dq]
|
|
fc: \[dq]\[dq]
|
|
- p: hello
|
|
isKey: true
|
|
hc: \[dq]\[dq]
|
|
lc: hello-world-comment
|
|
fc: \[dq]\[dq]
|
|
- p: hello
|
|
isKey: false
|
|
hc: \[dq]\[dq]
|
|
lc: \[dq]\[dq]
|
|
fc: \[dq]\[dq]
|
|
- p: hello.message
|
|
isKey: true
|
|
hc: \[dq]\[dq]
|
|
lc: \[dq]\[dq]
|
|
fc: \[dq]\[dq]
|
|
- p: hello.message
|
|
isKey: false
|
|
hc: \[dq]\[dq]
|
|
lc: \[dq]\[dq]
|
|
fc: \[dq]\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Retrieve comment - map key example
|
|
.PP
|
|
From the previous example, we know that the comment is on the `hello'
|
|
\f[I]key\f[R] as a lineComment
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
hello: # hello-world-comment
|
|
message: world
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].hello | key | line_comment\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
hello-world-comment
|
|
\f[R]
|
|
.fi
|
|
.SS Where is the comment - array example
|
|
.PP
|
|
The underlying yaml parser can assign comments in a document to
|
|
surprising nodes.
|
|
Use an expression like this to find where you comment is.
|
|
`p' indicates the path, `isKey' is if the node is a map key (as opposed
|
|
to a map value).
|
|
From this, you can see the `under-name-comment' is actually on the first
|
|
child
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name:
|
|
# under-name-comment
|
|
- first-array-child
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][... | {\[dq]p\[dq]: path | join(\[dq].\[dq]), \[dq]isKey\[dq]: is_key, \[dq]hc\[dq]: headComment, \[dq]lc\[dq]: lineComment, \[dq]fc\[dq]: footComment}]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- p: \[dq]\[dq]
|
|
isKey: false
|
|
hc: \[dq]\[dq]
|
|
lc: \[dq]\[dq]
|
|
fc: \[dq]\[dq]
|
|
- p: name
|
|
isKey: true
|
|
hc: \[dq]\[dq]
|
|
lc: \[dq]\[dq]
|
|
fc: \[dq]\[dq]
|
|
- p: name
|
|
isKey: false
|
|
hc: \[dq]\[dq]
|
|
lc: \[dq]\[dq]
|
|
fc: \[dq]\[dq]
|
|
- p: name.0
|
|
isKey: false
|
|
hc: under-name-comment
|
|
lc: \[dq]\[dq]
|
|
fc: \[dq]\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Retrieve comment - array example
|
|
.PP
|
|
From the previous example, we know that the comment is on the first
|
|
child as a headComment
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name:
|
|
# under-name-comment
|
|
- first-array-child
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].name[0] | headComment\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
under-name-comment
|
|
\f[R]
|
|
.fi
|
|
.SS Set head comment
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. head_comment=\[dq]single\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# single
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Set head comment of a map entry
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
f: foo
|
|
a:
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.a | key) head_comment=\[dq]single\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
f: foo
|
|
# single
|
|
a:
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Set foot comment, using an expression
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. foot_comment=.a\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
# cat
|
|
\f[R]
|
|
.fi
|
|
.SS Remove comment
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat # comment
|
|
b: dog # leave this
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a line_comment=\[dq]\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog # leave this
|
|
\f[R]
|
|
.fi
|
|
.SS Remove (strip) all comments
|
|
.PP
|
|
Note the use of \f[C]...\f[R] to ensure key nodes are included.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# hi
|
|
|
|
a: cat # comment
|
|
# great
|
|
b: # key comment
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]... comments=\[dq]\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b:
|
|
\f[R]
|
|
.fi
|
|
.SS Get line comment
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# welcome!
|
|
|
|
a: cat # meow
|
|
# have a great day
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | line_comment\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
meow
|
|
\f[R]
|
|
.fi
|
|
.SS Get head comment
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# welcome!
|
|
|
|
a: cat # meow
|
|
|
|
# have a great day
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. | head_comment\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
welcome!
|
|
\f[R]
|
|
.fi
|
|
.SS Head comment with document split
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# welcome!
|
|
---
|
|
# bob
|
|
a: cat # meow
|
|
|
|
# have a great day
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]head_comment\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
welcome!
|
|
bob
|
|
\f[R]
|
|
.fi
|
|
.SS Get foot comment
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# welcome!
|
|
|
|
a: cat # meow
|
|
|
|
# have a great day
|
|
# no really
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. | foot_comment\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
have a great day
|
|
no really
|
|
\f[R]
|
|
.fi
|
|
.SH Compare Operators
|
|
.PP
|
|
Comparison operators (\f[C]>\f[R], \f[C]>=\f[R], \f[C]<\f[R],
|
|
\f[C]<=\f[R]) can be used for comparing scalar values of the same time.
|
|
.PP
|
|
The following types are currently supported:
|
|
.IP \[bu] 2
|
|
numbers
|
|
.IP \[bu] 2
|
|
strings
|
|
.IP \[bu] 2
|
|
datetimes
|
|
.SS Related Operators
|
|
.IP \[bu] 2
|
|
equals / not equals (\f[C]==\f[R], \f[C]!=\f[R]) operators
|
|
here (https://mikefarah.gitbook.io/yq/operators/equals)
|
|
.IP \[bu] 2
|
|
boolean operators (\f[C]and\f[R], \f[C]or\f[R], \f[C]any\f[R] etc)
|
|
here (https://mikefarah.gitbook.io/yq/operators/boolean-operators)
|
|
.IP \[bu] 2
|
|
select operator here (https://mikefarah.gitbook.io/yq/operators/select)
|
|
.SS Compare numbers (>)
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 5
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a > .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Compare equal numbers (>=)
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 5
|
|
b: 5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a >= .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Compare strings
|
|
.PP
|
|
Compares strings by their bytecode.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: zoo
|
|
b: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a > .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Compare date times
|
|
.PP
|
|
You can compare date times.
|
|
Assumes RFC3339 date time format, see date-time
|
|
operators (https://mikefarah.gitbook.io/yq/operators/date-time-operators)
|
|
for more information.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T03:10:00Z
|
|
b: 2020-01-01T03:10:00Z
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a > .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Both sides are null: > is false
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq].a > .b\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Both sides are null: >= is true
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq].a >= .b\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SH Contains
|
|
.PP
|
|
This returns \f[C]true\f[R] if the context contains the passed in
|
|
parameter, and false otherwise.
|
|
For arrays, this will return true if the passed in array is contained
|
|
within the array.
|
|
For strings, it will return true if the string is a substring.
|
|
.PP
|
|
{% hint style=\[lq]warning\[rq] %}
|
|
.PP
|
|
\f[I]Note\f[R] that, just like jq, when checking if an array of strings
|
|
\f[C]contains\f[R] another, this will use \f[C]contains\f[R] and
|
|
\f[I]not\f[R] equals to check each string.
|
|
This means an expression like \f[C]contains([\[dq]cat\[dq]])\f[R] will
|
|
return true for an array \f[C][\[dq]cats\[dq]]\f[R].
|
|
.PP
|
|
See the \[lq]Array has a subset array\[rq] example below on how to check
|
|
for a subset.
|
|
.PP
|
|
{% endhint %}
|
|
.SS Array contains array
|
|
.PP
|
|
Array is equal or subset of
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foobar
|
|
- foobaz
|
|
- blarp
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]contains([\[dq]baz\[dq], \[dq]bar\[dq]])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Array has a subset array
|
|
.PP
|
|
Subtract the superset array from the subset, if there\[cq]s anything
|
|
left, it\[cq]s not a subset
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foobar
|
|
- foobaz
|
|
- blarp
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][\[dq]baz\[dq], \[dq]bar\[dq]] - . | length == 0\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Object included in array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\[dq]foo\[dq]: 12
|
|
\[dq]bar\[dq]:
|
|
- 1
|
|
- 2
|
|
- \[dq]barp\[dq]: 12
|
|
\[dq]blip\[dq]: 13
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]contains({\[dq]bar\[dq]: [{\[dq]barp\[dq]: 12}]})\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Object not included in array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\[dq]foo\[dq]: 12
|
|
\[dq]bar\[dq]:
|
|
- 1
|
|
- 2
|
|
- \[dq]barp\[dq]: 12
|
|
\[dq]blip\[dq]: 13
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]contains({\[dq]foo\[dq]: 12, \[dq]bar\[dq]: [{\[dq]barp\[dq]: 15}]})\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS String contains substring
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foobar
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]contains(\[dq]bar\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS String equals string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
meow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]contains(\[dq]meow\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SH Create, Collect into Object
|
|
.PP
|
|
This is used to construct objects (or maps).
|
|
This can be used against existing yaml, or to create fresh yaml
|
|
documents.
|
|
.SS Collect empty object
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]{}\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{}
|
|
\f[R]
|
|
.fi
|
|
.SS Wrap (prefix) existing object
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: Mike
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]{\[dq]wrap\[dq]: .}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
wrap:
|
|
name: Mike
|
|
\f[R]
|
|
.fi
|
|
.SS Using splat to create multiple objects
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: Mike
|
|
pets:
|
|
- cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]{.name: .pets.[]}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Mike: cat
|
|
Mike: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Working with multiple documents
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: Mike
|
|
pets:
|
|
- cat
|
|
- dog
|
|
---
|
|
name: Rosey
|
|
pets:
|
|
- monkey
|
|
- sheep
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]{.name: .pets.[]}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Mike: cat
|
|
Mike: dog
|
|
---
|
|
Rosey: monkey
|
|
Rosey: sheep
|
|
\f[R]
|
|
.fi
|
|
.SS Creating yaml from scratch
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]{\[dq]wrap\[dq]: \[dq]frog\[dq]}\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
wrap: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Creating yaml from scratch with multiple objects
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq](.a.b = \[dq]foo\[dq]) | (.d.e = \[dq]bar\[dq])\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: foo
|
|
d:
|
|
e: bar
|
|
\f[R]
|
|
.fi
|
|
.SH Date Time
|
|
.PP
|
|
Various operators for parsing and manipulating dates.
|
|
.SS Date time formattings
|
|
.PP
|
|
This uses Golang\[cq]s built in time library for parsing and formatting
|
|
date times.
|
|
.PP
|
|
When not specified, the RFC3339 standard is assumed
|
|
\f[C]2006-01-02T15:04:05Z07:00\f[R] for parsing.
|
|
.PP
|
|
To specify a custom parsing format, use the \f[C]with_dtf\f[R] operator.
|
|
The first parameter sets the datetime parsing format for the expression
|
|
in the second parameter.
|
|
The expression can be any valid \f[C]yq\f[R] expression tree.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_dtf(\[dq]myformat\[dq]; .a + \[dq]3h\[dq] | tz(\[dq]Australia/Melbourne\[dq]))\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
See the library docs (https://pkg.go.dev/time#pkg-constants) for
|
|
examples of formatting options.
|
|
.SS Timezones
|
|
.PP
|
|
This uses Golang\[cq]s built in LoadLocation function to parse timezones
|
|
strings.
|
|
See the library docs (https://pkg.go.dev/time#LoadLocation) for more
|
|
details.
|
|
.SS Durations
|
|
.PP
|
|
Durations are parsed using Golang\[cq]s built in
|
|
ParseDuration (https://pkg.go.dev/time#ParseDuration) function.
|
|
.PP
|
|
You can add durations to time using the \f[C]+\f[R] operator.
|
|
.SS Format: from standard RFC3339 format
|
|
.PP
|
|
Providing a single parameter assumes a standard RFC3339 datetime format.
|
|
If the target format is not a valid yaml datetime format, the result
|
|
will be a string tagged node.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2001-12-15T02:59:43.1Z
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= format_datetime(\[dq]Monday, 02-Jan-06 at 3:04PM\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:59AM
|
|
\f[R]
|
|
.fi
|
|
.SS Format: from custom date time
|
|
.PP
|
|
Use with_dtf to set a custom datetime format for parsing.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:59AM
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= with_dtf(\[dq]Monday, 02-Jan-06 at 3:04PM\[dq]; format_datetime(\[dq]2006-01-02\[dq]))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2001-12-15
|
|
\f[R]
|
|
.fi
|
|
.SS Format: get the day of the week
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2001-12-15
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | format_datetime(\[dq]Monday\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Saturday
|
|
\f[R]
|
|
.fi
|
|
.SS Now
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].updated = now\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cool
|
|
updated: 2021-05-19T01:02:03Z
|
|
\f[R]
|
|
.fi
|
|
.SS From Unix
|
|
.PP
|
|
Converts from unix time.
|
|
Note, you don\[cq]t have to pipe through the tz operator :)
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]1675301929 | from_unix | tz(\[dq]UTC\[dq])\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2023-02-02T01:38:49Z
|
|
\f[R]
|
|
.fi
|
|
.SS To Unix
|
|
.PP
|
|
Converts to unix time
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]now | to_unix\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1621386123
|
|
\f[R]
|
|
.fi
|
|
.SS Timezone: from standard RFC3339 format
|
|
.PP
|
|
Returns a new datetime in the specified timezone.
|
|
Specify standard IANA Time Zone format or `utc', `local'.
|
|
When given a single parameter, this assumes the datetime is in RFC3339
|
|
format.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].updated = (now | tz(\[dq]Australia/Sydney\[dq]))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cool
|
|
updated: 2021-05-19T11:02:03+10:00
|
|
\f[R]
|
|
.fi
|
|
.SS Timezone: with custom format
|
|
.PP
|
|
Specify standard IANA Time Zone format or `utc', `local'
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:59AM GMT
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= with_dtf(\[dq]Monday, 02-Jan-06 at 3:04PM MST\[dq]; tz(\[dq]Australia/Sydney\[dq]))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 1:59PM AEDT
|
|
\f[R]
|
|
.fi
|
|
.SS Add and tz custom format
|
|
.PP
|
|
Specify standard IANA Time Zone format or `utc', `local'
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:59AM GMT
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= with_dtf(\[dq]Monday, 02-Jan-06 at 3:04PM MST\[dq]; tz(\[dq]Australia/Sydney\[dq]))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 1:59PM AEDT
|
|
\f[R]
|
|
.fi
|
|
.SS Date addition
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T00:00:00Z
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a += \[dq]3h10m\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T03:10:00Z
|
|
\f[R]
|
|
.fi
|
|
.SS Date subtraction
|
|
.PP
|
|
You can subtract durations from dates.
|
|
Assumes RFC3339 date time format, see date-time
|
|
operators (https://mikefarah.gitbook.io/yq/operators/datetime#date-time-formattings)
|
|
for more information.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T03:10:00Z
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a -= \[dq]3h10m\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T00:00:00Z
|
|
\f[R]
|
|
.fi
|
|
.SS Date addition - custom format
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:59AM GMT
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_dtf(\[dq]Monday, 02-Jan-06 at 3:04PM MST\[dq]; .a += \[dq]3h1m\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 6:00AM GMT
|
|
\f[R]
|
|
.fi
|
|
.SS Date script with custom format
|
|
.PP
|
|
You can embed full expressions in with_dtf if needed.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:59AM GMT
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_dtf(\[dq]Monday, 02-Jan-06 at 3:04PM MST\[dq]; .a = (.a + \[dq]3h1m\[dq] | tz(\[dq]Australia/Perth\[dq])))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:00PM AWST
|
|
\f[R]
|
|
.fi
|
|
.SH Delete
|
|
.PP
|
|
Deletes matching entries in maps or arrays.
|
|
.SS Delete entry in map
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]del(.b)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Delete nested entry in map
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
a1: fred
|
|
a2: frood
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]del(.a.a1)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
a2: frood
|
|
\f[R]
|
|
.fi
|
|
.SS Delete entry in array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]del(.[1])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.SS Delete nested entry in array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]del(.[0].a)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- b: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Delete no matches
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]del(.c)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Delete matching entries
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
c: bat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]del( .[] | select(. == \[dq]*at\[dq]) )\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Recursively delete matching keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
name: frog
|
|
b:
|
|
name: blog
|
|
age: 12
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]del(.. | select(has(\[dq]name\[dq])).name)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
age: 12
|
|
\f[R]
|
|
.fi
|
|
.SH Divide
|
|
.PP
|
|
Divide behaves differently according to the type of the LHS: * strings:
|
|
split by the divider * number: arithmetic division
|
|
.SS String split
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat_meow
|
|
b: _
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].c = .a / .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat_meow
|
|
b: _
|
|
c:
|
|
- cat
|
|
- meow
|
|
\f[R]
|
|
.fi
|
|
.SS Number division
|
|
.PP
|
|
The result during division is calculated as a float
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 12
|
|
b: 2.5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a / .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 4.8
|
|
b: 2.5
|
|
\f[R]
|
|
.fi
|
|
.SS Number division by zero
|
|
.PP
|
|
Dividing by zero results in +Inf or -Inf
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: -1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a / 0 | .b = .b / 0\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !!float +Inf
|
|
b: !!float -Inf
|
|
\f[R]
|
|
.fi
|
|
.SH Document Index
|
|
.PP
|
|
Use the \f[C]documentIndex\f[R] operator (or the \f[C]di\f[R] shorthand)
|
|
to select nodes of a particular document.
|
|
.SS Retrieve a document index
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
---
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | document_index\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0
|
|
---
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS Retrieve a document index, shorthand
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
---
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | di\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0
|
|
---
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS Filter by document index
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
---
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]select(document_index == 1)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Filter by document index shorthand
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
---
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]select(di == 1)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Print Document Index with matches
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
---
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | ({\[dq]match\[dq]: ., \[dq]doc\[dq]: document_index})\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
match: cat
|
|
doc: 0
|
|
---
|
|
match: frog
|
|
doc: 1
|
|
\f[R]
|
|
.fi
|
|
.SH Encoder / Decoder
|
|
.PP
|
|
Encode operators will take the piped in object structure and encode it
|
|
as a string in the desired format.
|
|
The decode operators do the opposite, they take a formatted string and
|
|
decode it into the relevant object structure.
|
|
.PP
|
|
Note that you can optionally pass an indent value to the encode
|
|
functions (see below).
|
|
.PP
|
|
These operators are useful to process yaml documents that have
|
|
stringified embedded yaml/json/props in them.
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l l l.
|
|
T{
|
|
Format
|
|
T}@T{
|
|
Decode (from string)
|
|
T}@T{
|
|
Encode (to string)
|
|
T}
|
|
_
|
|
T{
|
|
Yaml
|
|
T}@T{
|
|
from_yaml/\[at]yamld
|
|
T}@T{
|
|
to_yaml(i)/\[at]yaml
|
|
T}
|
|
T{
|
|
JSON
|
|
T}@T{
|
|
from_json/\[at]jsond
|
|
T}@T{
|
|
to_json(i)/\[at]json
|
|
T}
|
|
T{
|
|
Properties
|
|
T}@T{
|
|
from_props/\[at]propsd
|
|
T}@T{
|
|
to_props/\[at]props
|
|
T}
|
|
T{
|
|
CSV
|
|
T}@T{
|
|
from_csv/\[at]csvd
|
|
T}@T{
|
|
to_csv/\[at]csv
|
|
T}
|
|
T{
|
|
TSV
|
|
T}@T{
|
|
from_tsv/\[at]tsvd
|
|
T}@T{
|
|
to_tsv/\[at]tsv
|
|
T}
|
|
T{
|
|
XML
|
|
T}@T{
|
|
from_xml/\[at]xmld
|
|
T}@T{
|
|
to_xml(i)/\[at]xml
|
|
T}
|
|
T{
|
|
Base64
|
|
T}@T{
|
|
\[at]base64d
|
|
T}@T{
|
|
\[at]base64
|
|
T}
|
|
T{
|
|
URI
|
|
T}@T{
|
|
\[at]urid
|
|
T}@T{
|
|
\[at]uri
|
|
T}
|
|
T{
|
|
Shell
|
|
T}@T{
|
|
T}@T{
|
|
\[at]sh
|
|
T}
|
|
.TE
|
|
.PP
|
|
See CSV and TSV
|
|
documentation (https://mikefarah.gitbook.io/yq/usage/csv-tsv) for
|
|
accepted formats.
|
|
.PP
|
|
XML uses the \f[C]--xml-attribute-prefix\f[R] and
|
|
\f[C]xml-content-name\f[R] flags to identify attributes and content
|
|
fields.
|
|
.PP
|
|
Base64 assumes rfc4648 (https://rfc-editor.org/rfc/rfc4648.html)
|
|
encoding.
|
|
Encoding and decoding both assume that the content is a utf-8 string and
|
|
not binary content.
|
|
.SS Encode value as json string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool: thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b = (.a | to_json)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool: thing
|
|
b: |
|
|
{
|
|
\[dq]cool\[dq]: \[dq]thing\[dq]
|
|
}
|
|
\f[R]
|
|
.fi
|
|
.SS Encode value as json string, on one line
|
|
.PP
|
|
Pass in a 0 indent to print json on a single line.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool: thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b = (.a | to_json(0))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool: thing
|
|
b: \[aq]{\[dq]cool\[dq]:\[dq]thing\[dq]}\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Encode value as json string, on one line shorthand
|
|
.PP
|
|
Pass in a 0 indent to print json on a single line.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool: thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b = (.a | \[at]json)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool: thing
|
|
b: \[aq]{\[dq]cool\[dq]:\[dq]thing\[dq]}\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Decode a json encoded string
|
|
.PP
|
|
Keep in mind JSON is a subset of YAML.
|
|
If you want idiomatic yaml, pipe through the style operator to clear out
|
|
the JSON styling.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[aq]{\[dq]cool\[dq]:\[dq]thing\[dq]}\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | from_json | ... style=\[dq]\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool: thing
|
|
\f[R]
|
|
.fi
|
|
.SS Encode value as props string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool: thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b = (.a | \[at]props)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool: thing
|
|
b: |
|
|
cool = thing
|
|
\f[R]
|
|
.fi
|
|
.SS Decode props encoded string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: |-
|
|
cats=great
|
|
dogs=cool as well
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= \[at]propsd\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cats: great
|
|
dogs: cool as well
|
|
\f[R]
|
|
.fi
|
|
.SS Decode csv encoded string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: |-
|
|
cats,dogs
|
|
great,cool as well
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= \[at]csvd\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cats: great
|
|
dogs: cool as well
|
|
\f[R]
|
|
.fi
|
|
.SS Decode tsv encoded string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: |-
|
|
cats dogs
|
|
great cool as well
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= \[at]tsvd\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cats: great
|
|
dogs: cool as well
|
|
\f[R]
|
|
.fi
|
|
.SS Encode value as yaml string
|
|
.PP
|
|
Indent defaults to 2
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool:
|
|
bob: dylan
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b = (.a | to_yaml)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool:
|
|
bob: dylan
|
|
b: |
|
|
cool:
|
|
bob: dylan
|
|
\f[R]
|
|
.fi
|
|
.SS Encode value as yaml string, with custom indentation
|
|
.PP
|
|
You can specify the indentation level as the first parameter.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool:
|
|
bob: dylan
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b = (.a | to_yaml(8))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool:
|
|
bob: dylan
|
|
b: |
|
|
cool:
|
|
bob: dylan
|
|
\f[R]
|
|
.fi
|
|
.SS Decode a yaml encoded string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[aq]foo: bar\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b = (.a | from_yaml)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[aq]foo: bar\[aq]
|
|
b:
|
|
foo: bar
|
|
\f[R]
|
|
.fi
|
|
.SS Update a multiline encoded yaml string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: |
|
|
foo: bar
|
|
baz: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= (from_yaml | .foo = \[dq]cat\[dq] | to_yaml)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: |
|
|
foo: cat
|
|
baz: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Update a single line encoded yaml string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[aq]foo: bar\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= (from_yaml | .foo = \[dq]cat\[dq] | to_yaml)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[aq]foo: cat\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Encode array of scalars as csv string
|
|
.PP
|
|
Scalars are strings, numbers and booleans.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- thing1,thing2
|
|
- true
|
|
- 3.40
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]\[at]csv\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat,\[dq]thing1,thing2\[dq],true,3.40
|
|
\f[R]
|
|
.fi
|
|
.SS Encode array of arrays as csv string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - cat
|
|
- thing1,thing2
|
|
- true
|
|
- 3.40
|
|
- - dog
|
|
- thing3
|
|
- false
|
|
- 12
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]\[at]csv\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat,\[dq]thing1,thing2\[dq],true,3.40
|
|
dog,thing3,false,12
|
|
\f[R]
|
|
.fi
|
|
.SS Encode array of arrays as tsv string
|
|
.PP
|
|
Scalars are strings, numbers and booleans.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - cat
|
|
- thing1,thing2
|
|
- true
|
|
- 3.40
|
|
- - dog
|
|
- thing3
|
|
- false
|
|
- 12
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]\[at]tsv\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat thing1,thing2 true 3.40
|
|
dog thing3 false 12
|
|
\f[R]
|
|
.fi
|
|
.SS Encode value as xml string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool:
|
|
foo: bar
|
|
+\[at]id: hi
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | to_xml\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<cool id=\[dq]hi\[dq]>
|
|
<foo>bar</foo>
|
|
</cool>
|
|
\f[R]
|
|
.fi
|
|
.SS Encode value as xml string on a single line
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool:
|
|
foo: bar
|
|
+\[at]id: hi
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | \[at]xml\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<cool id=\[dq]hi\[dq]><foo>bar</foo></cool>
|
|
\f[R]
|
|
.fi
|
|
.SS Encode value as xml string with custom indentation
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cool:
|
|
foo: bar
|
|
+\[at]id: hi
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]{\[dq]cat\[dq]: .a | to_xml(1)}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat: |
|
|
<cool id=\[dq]hi\[dq]>
|
|
<foo>bar</foo>
|
|
</cool>
|
|
\f[R]
|
|
.fi
|
|
.SS Decode a xml encoded string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: <foo>bar</foo>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b = (.a | from_xml)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: <foo>bar</foo>
|
|
b:
|
|
foo: bar
|
|
\f[R]
|
|
.fi
|
|
.SS Encode a string to base64
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
coolData: a special string
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].coolData | \[at]base64\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
YSBzcGVjaWFsIHN0cmluZw==
|
|
\f[R]
|
|
.fi
|
|
.SS Encode a yaml document to base64
|
|
.PP
|
|
Pipe through \[at]yaml first to convert to a string, then use
|
|
\[at]base64 to encode it.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]\[at]yaml | \[at]base64\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
YTogYXBwbGUK
|
|
\f[R]
|
|
.fi
|
|
.SS Encode a string to uri
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
coolData: this has & special () characters *
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].coolData | \[at]uri\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
this+has+%26+special+%28%29+characters+%2A
|
|
\f[R]
|
|
.fi
|
|
.SS Decode a URI to a string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
this+has+%26+special+%28%29+characters+%2A
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]\[at]urid\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
this has & special () characters *
|
|
\f[R]
|
|
.fi
|
|
.SS Encode a string to sh
|
|
.PP
|
|
Sh/Bash friendly string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
coolData: strings with spaces and a \[aq]quote\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].coolData | \[at]sh\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
strings\[aq] with spaces and a \[aq]\[rs]\[aq]quote\[rs]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Decode a base64 encoded string
|
|
.PP
|
|
Decoded data is assumed to be a string.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
coolData: V29ya3Mgd2l0aCBVVEYtMTYg8J+Yig==
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].coolData | \[at]base64d\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Works with UTF-16 \[u1F60A]
|
|
\f[R]
|
|
.fi
|
|
.SS Decode a base64 encoded yaml document
|
|
.PP
|
|
Pipe through \f[C]from_yaml\f[R] to parse the decoded base64 string as a
|
|
yaml document.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
coolData: YTogYXBwbGUK
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].coolData |= (\[at]base64d | from_yaml)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
coolData:
|
|
a: apple
|
|
\f[R]
|
|
.fi
|
|
.SH Entries
|
|
.PP
|
|
Similar to the same named functions in \f[C]jq\f[R] these functions
|
|
convert to/from an object and an array of key-value pairs.
|
|
This is most useful for performing operations on keys of maps.
|
|
.PP
|
|
Use \f[C]with_entries(op)\f[R] as a syntatic sugar for doing
|
|
\f[C]to_entries | op | from_entries\f[R].
|
|
.SS to_entries Map
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: 2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]to_entries\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- key: a
|
|
value: 1
|
|
- key: b
|
|
value: 2
|
|
\f[R]
|
|
.fi
|
|
.SS to_entries Array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a
|
|
- b
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]to_entries\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- key: 0
|
|
value: a
|
|
- key: 1
|
|
value: b
|
|
\f[R]
|
|
.fi
|
|
.SS to_entries null
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
null
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]to_entries\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\f[R]
|
|
.fi
|
|
.SS from_entries map
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: 2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]to_entries | from_entries\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: 2
|
|
\f[R]
|
|
.fi
|
|
.SS from_entries with numeric key indices
|
|
.PP
|
|
from_entries always creates a map, even for numeric keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a
|
|
- b
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]to_entries | from_entries\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0: a
|
|
1: b
|
|
\f[R]
|
|
.fi
|
|
.SS Use with_entries to update keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: 2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_entries(.key |= \[dq]KEY_\[dq] + .)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
KEY_a: 1
|
|
KEY_b: 2
|
|
\f[R]
|
|
.fi
|
|
.SS Use with_entries to update keys recursively
|
|
.PP
|
|
We use (..
|
|
| select(tag=\[lq]map\[rq])) to find all the maps in the doc, then |= to
|
|
update each one of those maps.
|
|
In the update, with_entries is used.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b:
|
|
b_a: nested
|
|
b_b: thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.. | select(tag==\[dq]!!map\[dq])) |= with_entries(.key |= \[dq]KEY_\[dq] + .)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
KEY_a: 1
|
|
KEY_b:
|
|
KEY_b_a: nested
|
|
KEY_b_b: thing
|
|
\f[R]
|
|
.fi
|
|
.SS Custom sort map keys
|
|
.PP
|
|
Use to_entries to convert to an array of key/value pairs, sort the array
|
|
using sort/sort_by/etc, and convert it back.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
c: 3
|
|
b: 2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]to_entries | sort_by(.key) | reverse | from_entries\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
c: 3
|
|
b: 2
|
|
a: 1
|
|
\f[R]
|
|
.fi
|
|
.SS Use with_entries to filter the map
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: bird
|
|
c:
|
|
d: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_entries(select(.value | has(\[dq]b\[dq])))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: bird
|
|
\f[R]
|
|
.fi
|
|
.SH Env Variable Operators
|
|
.PP
|
|
These operators are used to handle environment variables usage in
|
|
expressions and documents.
|
|
While environment variables can, of course, be passed in via your CLI
|
|
with string interpolation, this often comes with complex quote escaping
|
|
and can be tricky to write and read.
|
|
.PP
|
|
There are three operators:
|
|
.IP \[bu] 2
|
|
\f[C]env\f[R] which takes a single environment variable name and parse
|
|
the variable as a yaml node (be it a map, array, string, number of
|
|
boolean)
|
|
.IP \[bu] 2
|
|
\f[C]strenv\f[R] which also takes a single environment variable name,
|
|
and always parses the variable as a string.
|
|
.IP \[bu] 2
|
|
\f[C]envsubst\f[R] which you pipe strings into and it interpolates
|
|
environment variables in strings using
|
|
envsubst (https://github.com/a8m/envsubst).
|
|
.SS EnvSubst Options
|
|
.PP
|
|
You can optionally pass envsubst any of the following options:
|
|
.IP \[bu] 2
|
|
nu: NoUnset, this will fail if there are any referenced variables that
|
|
are not set
|
|
.IP \[bu] 2
|
|
ne: NoEmpty, this will fail if there are any referenced variables that
|
|
are empty
|
|
.IP \[bu] 2
|
|
ff: FailFast, this will abort on the first failure (rather than collect
|
|
all the errors)
|
|
.PP
|
|
E.g: \f[C]envsubst(ne, ff)\f[R] will fail on the first empty variable.
|
|
.PP
|
|
See Imposing
|
|
Restrictions (https://github.com/a8m/envsubst#imposing-restrictions) in
|
|
the \f[C]envsubst\f[R] documentation for more information, and below for
|
|
examples.
|
|
.SS Tip
|
|
.PP
|
|
To replace environment variables across all values in a document,
|
|
\f[C]envsubst\f[R] can be used with the recursive descent operator as
|
|
follows:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.. | select(tag == \[dq]!!str\[dq])) |= envsubst\[aq] file.yaml
|
|
\f[R]
|
|
.fi
|
|
.SS Read string environment variable
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]cat meow\[dq] yq --null-input \[aq].a = env(myenv)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat meow
|
|
\f[R]
|
|
.fi
|
|
.SS Read boolean environment variable
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]true\[dq] yq --null-input \[aq].a = env(myenv)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: true
|
|
\f[R]
|
|
.fi
|
|
.SS Read numeric environment variable
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]12\[dq] yq --null-input \[aq].a = env(myenv)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 12
|
|
\f[R]
|
|
.fi
|
|
.SS Read yaml environment variable
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]{b: fish}\[dq] yq --null-input \[aq].a = env(myenv)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: {b: fish}
|
|
\f[R]
|
|
.fi
|
|
.SS Read boolean environment variable as a string
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]true\[dq] yq --null-input \[aq].a = strenv(myenv)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[dq]true\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Read numeric environment variable as a string
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]12\[dq] yq --null-input \[aq].a = strenv(myenv)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[dq]12\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Dynamically update a path from an environment variable
|
|
.PP
|
|
The env variable can be any valid yq expression.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
- name: dog
|
|
- name: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
pathEnv=\[dq].a.b[0].name\[dq] valueEnv=\[dq]moo\[dq] yq \[aq]eval(strenv(pathEnv)) = strenv(valueEnv)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
- name: moo
|
|
- name: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Dynamic key lookup with environment variable
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat: meow
|
|
dog: woof
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]cat\[dq] yq \[aq].[env(myenv)]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
meow
|
|
\f[R]
|
|
.fi
|
|
.SS Replace strings with envsubst
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]cat\[dq] yq --null-input \[aq]\[dq]the ${myenv} meows\[dq] | envsubst\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
the cat meows
|
|
\f[R]
|
|
.fi
|
|
.SS Replace strings with envsubst, missing variables
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]the ${myenvnonexisting} meows\[dq] | envsubst\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
the meows
|
|
\f[R]
|
|
.fi
|
|
.SS Replace strings with envsubst(nu), missing variables
|
|
.PP
|
|
(nu) not unset, will fail if there are unset (missing) variables
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]the ${myenvnonexisting} meows\[dq] | envsubst(nu)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: variable ${myenvnonexisting} not set
|
|
\f[R]
|
|
.fi
|
|
.SS Replace strings with envsubst(ne), missing variables
|
|
.PP
|
|
(ne) not empty, only validates set variables
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]the ${myenvnonexisting} meows\[dq] | envsubst(ne)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
the meows
|
|
\f[R]
|
|
.fi
|
|
.SS Replace strings with envsubst(ne), empty variable
|
|
.PP
|
|
(ne) not empty, will fail if a references variable is empty
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]\[dq] yq --null-input \[aq]\[dq]the ${myenv} meows\[dq] | envsubst(ne)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: variable ${myenv} set but empty
|
|
\f[R]
|
|
.fi
|
|
.SS Replace strings with envsubst, missing variables with defaults
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]the ${myenvnonexisting-dog} meows\[dq] | envsubst\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
the dog meows
|
|
\f[R]
|
|
.fi
|
|
.SS Replace strings with envsubst(nu), missing variables with defaults
|
|
.PP
|
|
Having a default specified skips over the missing variable.
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]the ${myenvnonexisting-dog} meows\[dq] | envsubst(nu)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
the dog meows
|
|
\f[R]
|
|
.fi
|
|
.SS Replace strings with envsubst(ne), missing variables with defaults
|
|
.PP
|
|
Fails, because the variable is explicitly set to blank.
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myEmptyEnv=\[dq]\[dq] yq --null-input \[aq]\[dq]the ${myEmptyEnv-dog} meows\[dq] | envsubst(ne)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: variable ${myEmptyEnv} set but empty
|
|
\f[R]
|
|
.fi
|
|
.SS Replace string environment variable in document
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
v: ${myenv}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myenv=\[dq]cat meow\[dq] yq \[aq].v |= envsubst\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
v: cat meow
|
|
\f[R]
|
|
.fi
|
|
.SS (Default) Return all envsubst errors
|
|
.PP
|
|
By default, all errors are returned at once.
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]the ${notThere} ${alsoNotThere}\[dq] | envsubst(nu)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: variable ${notThere} not set
|
|
variable ${alsoNotThere} not set
|
|
\f[R]
|
|
.fi
|
|
.SS Fail fast, return the first envsubst error (and abort)
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]\[dq]the ${notThere} ${alsoNotThere}\[dq] | envsubst(nu,ff)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: variable ${notThere} not set
|
|
\f[R]
|
|
.fi
|
|
.SH Equals / Not Equals
|
|
.PP
|
|
This is a boolean operator that will return \f[C]true\f[R] if the LHS is
|
|
equal to the RHS and \f[C]false\f[R] otherwise.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\&.a == .b
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
It is most often used with the select operator to find particular nodes:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
select(.a == .b)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
The not equals \f[C]!=\f[R] operator returns \f[C]false\f[R] if the LHS
|
|
is equal to the RHS.
|
|
.SS Related Operators
|
|
.IP \[bu] 2
|
|
comparison (\f[C]>=\f[R], \f[C]<\f[R] etc) operators
|
|
here (https://mikefarah.gitbook.io/yq/operators/compare)
|
|
.IP \[bu] 2
|
|
boolean operators (\f[C]and\f[R], \f[C]or\f[R], \f[C]any\f[R] etc)
|
|
here (https://mikefarah.gitbook.io/yq/operators/boolean-operators)
|
|
.IP \[bu] 2
|
|
select operator here (https://mikefarah.gitbook.io/yq/operators/select)
|
|
.SS Match string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- goat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | (. == \[dq]*at\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
true
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Don\[cq]t match string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- goat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | (. != \[dq]*at\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
false
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Match number
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 3
|
|
- 4
|
|
- 5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | (. == 4)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
true
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Don\[cq]t match number
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 3
|
|
- 4
|
|
- 5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | (. != 4)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
false
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Match nulls
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]null == \[ti]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SS Non existent key doesn\[cq]t equal a value
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]select(.b != \[dq]thing\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Two non existent keys are equal
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]select(.b == .c)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.SH Error
|
|
.PP
|
|
Use this operation to short-circuit expressions.
|
|
Useful for validation.
|
|
.SS Validate a particular value
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: hello
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]select(.a == \[dq]howdy\[dq]) or error(\[dq].a [\[dq] + .a + \[dq]] is not howdy!\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: .a [hello] is not howdy!
|
|
\f[R]
|
|
.fi
|
|
.SS Validate the environment variable is a number - invalid
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
numberOfCats=\[dq]please\[dq] yq --null-input \[aq]env(numberOfCats) | select(tag == \[dq]!!int\[dq]) or error(\[dq]numberOfCats is not a number :(\[dq])\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: numberOfCats is not a number :(
|
|
\f[R]
|
|
.fi
|
|
.SS Validate the environment variable is a number - valid
|
|
.PP
|
|
\f[C]with\f[R] can be a convenient way of encapsulating validation.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: Bob
|
|
favouriteAnimal: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
numberOfCats=\[dq]3\[dq] yq \[aq]
|
|
with(env(numberOfCats); select(tag == \[dq]!!int\[dq]) or error(\[dq]numberOfCats is not a number :(\[dq])) |
|
|
.numPets = env(numberOfCats)
|
|
\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: Bob
|
|
favouriteAnimal: cat
|
|
numPets: 3
|
|
\f[R]
|
|
.fi
|
|
.SH Eval
|
|
.PP
|
|
Use \f[C]eval\f[R] to dynamically process an expression - for instance
|
|
from an environment variable.
|
|
.PP
|
|
\f[C]eval\f[R] takes a single argument, and evaluates that as a
|
|
\f[C]yq\f[R] expression.
|
|
Any valid expression can be used, be it a path
|
|
\f[C].a.b.c | select(. == \[dq]cat\[dq])\f[R], or an update
|
|
\f[C].a.b.c = \[dq]gogo\[dq]\f[R].
|
|
.PP
|
|
Tip: This can be a useful way to parameterise complex scripts.
|
|
.SS Dynamically evaluate a path
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
pathExp: .a.b[] | select(.name == \[dq]cat\[dq])
|
|
a:
|
|
b:
|
|
- name: dog
|
|
- name: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]eval(.pathExp)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Dynamically update a path from an environment variable
|
|
.PP
|
|
The env variable can be any valid yq expression.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
- name: dog
|
|
- name: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
pathEnv=\[dq].a.b[0].name\[dq] valueEnv=\[dq]moo\[dq] yq \[aq]eval(strenv(pathEnv)) = strenv(valueEnv)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
- name: moo
|
|
- name: cat
|
|
\f[R]
|
|
.fi
|
|
.SH File Operators
|
|
.PP
|
|
File operators are most often used with merge when needing to merge
|
|
specific files together.
|
|
Note that when doing this, you will need to use \f[C]eval-all\f[R] to
|
|
ensure all yaml documents are loaded into memory before performing the
|
|
merge (as opposed to \f[C]eval\f[R] which runs the expression once per
|
|
document).
|
|
.PP
|
|
Note that the \f[C]fileIndex\f[R] operator has a short alias of
|
|
\f[C]fi\f[R].
|
|
.SS Merging files
|
|
.PP
|
|
Note the use of eval-all to ensure all documents are loaded into memory.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq eval-all \[aq]select(fi == 0) * select(filename == \[dq]file2.yaml\[dq])\[aq] file1.yaml file2.yaml
|
|
\f[R]
|
|
.fi
|
|
.SS Get filename
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]filename\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
sample.yml
|
|
\f[R]
|
|
.fi
|
|
.SS Get file index
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]file_index\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0
|
|
\f[R]
|
|
.fi
|
|
.SS Get file indices of multiple documents
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
And another sample another.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq eval-all \[aq]file_index\[aq] sample.yml another.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS Get file index alias
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]fi\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0
|
|
\f[R]
|
|
.fi
|
|
.SH Filter
|
|
.PP
|
|
Filters an array (or map values) by the expression given.
|
|
Equivalent to doing \f[C]map(select(exp))\f[R].
|
|
.SS Filter array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]filter(. < 3)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
\f[R]
|
|
.fi
|
|
.SS Filter map values
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
c:
|
|
things: cool
|
|
frog: yes
|
|
d:
|
|
things: hot
|
|
frog: false
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]filter(.things == \[dq]cool\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- things: cool
|
|
frog: yes
|
|
\f[R]
|
|
.fi
|
|
.SH Flatten
|
|
.PP
|
|
This recursively flattens arrays.
|
|
.SS Flatten
|
|
.PP
|
|
Recursively flattens all arrays
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- - 2
|
|
- - - 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]flatten\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.SS Flatten with depth of one
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- - 2
|
|
- - - 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]flatten(1)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- - 3
|
|
\f[R]
|
|
.fi
|
|
.SS Flatten empty array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]flatten\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[]
|
|
\f[R]
|
|
.fi
|
|
.SS Flatten array of objects
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foo: bar
|
|
- - foo: baz
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]flatten\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foo: bar
|
|
- foo: baz
|
|
\f[R]
|
|
.fi
|
|
.SH Group By
|
|
.PP
|
|
This is used to group items in an array by an expression.
|
|
.SS Group by field
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foo: 1
|
|
bar: 10
|
|
- foo: 3
|
|
bar: 100
|
|
- foo: 1
|
|
bar: 1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]group_by(.foo)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - foo: 1
|
|
bar: 10
|
|
- foo: 1
|
|
bar: 1
|
|
- - foo: 3
|
|
bar: 100
|
|
\f[R]
|
|
.fi
|
|
.SS Group by field, with nulls
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat: dog
|
|
- foo: 1
|
|
bar: 10
|
|
- foo: 3
|
|
bar: 100
|
|
- no: foo for you
|
|
- foo: 1
|
|
bar: 1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]group_by(.foo)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - cat: dog
|
|
- no: foo for you
|
|
- - foo: 1
|
|
bar: 10
|
|
- foo: 1
|
|
bar: 1
|
|
- - foo: 3
|
|
bar: 100
|
|
\f[R]
|
|
.fi
|
|
.SH Has
|
|
.PP
|
|
This operation returns true if the key exists in a map (or index in an
|
|
array), false otherwise.
|
|
.SS Has map key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: yes
|
|
- a: \[ti]
|
|
- a:
|
|
- b: nope
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | has(\[dq]a\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
true
|
|
true
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Select, checking for existence of deep paths
|
|
.PP
|
|
Simply pipe in parent expressions into \f[C]has\f[R]
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a:
|
|
b:
|
|
c: cat
|
|
- a:
|
|
b:
|
|
d: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | select(.a.b | has(\[dq]c\[dq]))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
c: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Has array index
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- []
|
|
- [1]
|
|
- [1, 2]
|
|
- [1, null]
|
|
- [1, 2, 3]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | has(1)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
false
|
|
false
|
|
true
|
|
true
|
|
true
|
|
\f[R]
|
|
.fi
|
|
.SH Keys
|
|
.PP
|
|
Use the \f[C]keys\f[R] operator to return map keys or array indices.
|
|
.SS Map keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
dog: woof
|
|
cat: meow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]keys\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- dog
|
|
- cat
|
|
\f[R]
|
|
.fi
|
|
.SS Array keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- apple
|
|
- banana
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]keys\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 0
|
|
- 1
|
|
\f[R]
|
|
.fi
|
|
.SS Retrieve array key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[1] | key\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS Retrieve map key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | key\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a
|
|
\f[R]
|
|
.fi
|
|
.SS No key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]key\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\f[R]
|
|
.fi
|
|
.SS Update map key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
x: 3
|
|
y: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.a.x | key) = \[dq]meow\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
meow: 3
|
|
y: 4
|
|
\f[R]
|
|
.fi
|
|
.SS Get comment from map key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
# comment on key
|
|
x: 3
|
|
y: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.x | key | headComment\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
comment on key
|
|
\f[R]
|
|
.fi
|
|
.SS Check node is a key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
- cat
|
|
c: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][... | { \[dq]p\[dq]: path | join(\[dq].\[dq]), \[dq]isKey\[dq]: is_key, \[dq]tag\[dq]: tag }]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- p: \[dq]\[dq]
|
|
isKey: false
|
|
tag: \[aq]!!map\[aq]
|
|
- p: a
|
|
isKey: true
|
|
tag: \[aq]!!str\[aq]
|
|
- p: a
|
|
isKey: false
|
|
tag: \[aq]!!map\[aq]
|
|
- p: a.b
|
|
isKey: true
|
|
tag: \[aq]!!str\[aq]
|
|
- p: a.b
|
|
isKey: false
|
|
tag: \[aq]!!seq\[aq]
|
|
- p: a.b.0
|
|
isKey: false
|
|
tag: \[aq]!!str\[aq]
|
|
- p: a.c
|
|
isKey: true
|
|
tag: \[aq]!!str\[aq]
|
|
- p: a.c
|
|
isKey: false
|
|
tag: \[aq]!!str\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SH Kind
|
|
.PP
|
|
The \f[C]kind\f[R] operator identifies the type of a node as either
|
|
\f[C]scalar\f[R], \f[C]map\f[R], or \f[C]seq\f[R].
|
|
.PP
|
|
This can be used for filtering or transforming nodes based on their
|
|
type.
|
|
.PP
|
|
Note that \f[C]null\f[R] values are treated as \f[C]scalar\f[R].
|
|
.SS Get kind
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f: []
|
|
g: {}
|
|
h: null
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. | kind\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
map
|
|
scalar
|
|
scalar
|
|
scalar
|
|
scalar
|
|
seq
|
|
map
|
|
scalar
|
|
\f[R]
|
|
.fi
|
|
.SS Get kind, ignores custom tags
|
|
.PP
|
|
Unlike tag, kind is not affected by custom tags.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !!thing cat
|
|
b: !!foo {}
|
|
c: !!bar []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. | kind\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
map
|
|
scalar
|
|
map
|
|
seq
|
|
\f[R]
|
|
.fi
|
|
.SS Add comments only to scalars
|
|
.PP
|
|
An example of how you can use kind
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f: []
|
|
g: {}
|
|
h: null
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.. | select(kind == \[dq]scalar\[dq])) line_comment = \[dq]this is a scalar\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: 5 # this is a scalar
|
|
c: 3.2 # this is a scalar
|
|
e: true # this is a scalar
|
|
f: []
|
|
g: {}
|
|
h: null # this is a scalar
|
|
\f[R]
|
|
.fi
|
|
.SH Length
|
|
.PP
|
|
Returns the lengths of the nodes.
|
|
Length is defined according to the type of the node.
|
|
.SS String length
|
|
.PP
|
|
returns length of string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | length\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
3
|
|
\f[R]
|
|
.fi
|
|
.SS null length
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: null
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | length\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0
|
|
\f[R]
|
|
.fi
|
|
.SS Map length
|
|
.PP
|
|
returns number of entries
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
c: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]length\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2
|
|
\f[R]
|
|
.fi
|
|
.SS Array length
|
|
.PP
|
|
returns number of elements
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 2
|
|
- 4
|
|
- 6
|
|
- 8
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]length\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
4
|
|
\f[R]
|
|
.fi
|
|
.SH Line
|
|
.PP
|
|
Returns the line of the matching node.
|
|
Starts from 1, 0 indicates there was no line data.
|
|
.SS Returns line of \f[I]value\f[R] node
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b:
|
|
c: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b | line\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
3
|
|
\f[R]
|
|
.fi
|
|
.SS Returns line of \f[I]key\f[R] node
|
|
.PP
|
|
Pipe through the key operator to get the line of the key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b:
|
|
c: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b | key | line\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2
|
|
\f[R]
|
|
.fi
|
|
.SS First line is 1
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | line\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS No line data is 0
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]{\[dq]a\[dq]: \[dq]new entry\[dq]} | line\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
0
|
|
\f[R]
|
|
.fi
|
|
.SH Load
|
|
.PP
|
|
The load operators allows you to load in content from another file.
|
|
.PP
|
|
Note that you can use string operators like \f[C]+\f[R] and
|
|
\f[C]sub\f[R] to modify the value in the yaml file to a path that exists
|
|
in your system.
|
|
.PP
|
|
You can load files of the following supported types:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l l.
|
|
T{
|
|
Format
|
|
T}@T{
|
|
Load Operator
|
|
T}
|
|
_
|
|
T{
|
|
Yaml
|
|
T}@T{
|
|
load
|
|
T}
|
|
T{
|
|
XML
|
|
T}@T{
|
|
load_xml
|
|
T}
|
|
T{
|
|
Properties
|
|
T}@T{
|
|
load_props
|
|
T}
|
|
T{
|
|
Plain String
|
|
T}@T{
|
|
load_str
|
|
T}
|
|
T{
|
|
Base64
|
|
T}@T{
|
|
load_base64
|
|
T}
|
|
.TE
|
|
.PP
|
|
Note that load_base64 only works for base64 encoded utf-8 strings.
|
|
.SS Samples files for tests:
|
|
.SS yaml
|
|
.PP
|
|
\f[C]../../examples/thing.yml\f[R]:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: apple is included
|
|
b: cool
|
|
\f[R]
|
|
.fi
|
|
.SS xml
|
|
.PP
|
|
\f[C]small.xml\f[R]:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<this>is some xml</this>
|
|
\f[R]
|
|
.fi
|
|
.SS properties
|
|
.PP
|
|
\f[C]small.properties\f[R]:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
this.is = a properties file
|
|
\f[R]
|
|
.fi
|
|
.SS base64
|
|
.PP
|
|
\f[C]base64.txt\f[R]:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bXkgc2VjcmV0IGNoaWxsaSByZWNpcGUgaXMuLi4u
|
|
\f[R]
|
|
.fi
|
|
.SS Simple example
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myFile: ../../examples/thing.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]load(.myFile)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: apple is included
|
|
b: cool.
|
|
\f[R]
|
|
.fi
|
|
.SS Replace node with referenced file
|
|
.PP
|
|
Note that you can modify the filename in the load operator if needed.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
something:
|
|
file: thing.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].something |= load(\[dq]../../examples/\[dq] + .file)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
something:
|
|
a: apple is included
|
|
b: cool.
|
|
\f[R]
|
|
.fi
|
|
.SS Replace \f[I]all\f[R] nodes with referenced file
|
|
.PP
|
|
Recursively match all the nodes (\f[C]..\f[R]) and then filter the ones
|
|
that have a `file' attribute.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
something:
|
|
file: thing.yml
|
|
over:
|
|
here:
|
|
- file: thing.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.. | select(has(\[dq]file\[dq]))) |= load(\[dq]../../examples/\[dq] + .file)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
something:
|
|
a: apple is included
|
|
b: cool.
|
|
over:
|
|
here:
|
|
- a: apple is included
|
|
b: cool.
|
|
\f[R]
|
|
.fi
|
|
.SS Replace node with referenced file as string
|
|
.PP
|
|
This will work for any text based file
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
something:
|
|
file: thing.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].something |= load_str(\[dq]../../examples/\[dq] + .file)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
something: |-
|
|
a: apple is included
|
|
b: cool.
|
|
\f[R]
|
|
.fi
|
|
.SS Load from XML
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool: things
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].more_stuff = load_xml(\[dq]../../examples/small.xml\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool: things
|
|
more_stuff:
|
|
this: is some xml
|
|
\f[R]
|
|
.fi
|
|
.SS Load from Properties
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool: things
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].more_stuff = load_props(\[dq]../../examples/small.properties\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool: things
|
|
more_stuff:
|
|
this:
|
|
is: a properties file
|
|
\f[R]
|
|
.fi
|
|
.SS Merge from properties
|
|
.PP
|
|
This can be used as a convenient way to update a yaml document
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
this:
|
|
is: from yaml
|
|
cool: ay
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. *= load_props(\[dq]../../examples/small.properties\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
this:
|
|
is: a properties file
|
|
cool: ay
|
|
\f[R]
|
|
.fi
|
|
.SS Load from base64 encoded file
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool: things
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].more_stuff = load_base64(\[dq]../../examples/base64.txt\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool: things
|
|
more_stuff: my secret chilli recipe is....
|
|
\f[R]
|
|
.fi
|
|
.SH Map
|
|
.PP
|
|
Maps values of an array.
|
|
Use \f[C]map_values\f[R] to map values of an object.
|
|
.SS Map array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]map(. + 1)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 2
|
|
- 3
|
|
- 4
|
|
\f[R]
|
|
.fi
|
|
.SS Map object values
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: 2
|
|
c: 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]map_values(. + 1)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2
|
|
b: 3
|
|
c: 4
|
|
\f[R]
|
|
.fi
|
|
.SH Max
|
|
.PP
|
|
Computes the maximum among an incoming sequence of scalar values.
|
|
.SS Maximum int
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 99
|
|
- 16
|
|
- 12
|
|
- 6
|
|
- 66
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]max\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
99
|
|
\f[R]
|
|
.fi
|
|
.SS Maximum string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foo
|
|
- bar
|
|
- baz
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]max\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo
|
|
\f[R]
|
|
.fi
|
|
.SS Maximum of empty
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]max\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\f[R]
|
|
.fi
|
|
.SH Min
|
|
.PP
|
|
Computes the minimum among an incoming sequence of scalar values.
|
|
.SS Minimum int
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 99
|
|
- 16
|
|
- 12
|
|
- 6
|
|
- 66
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]min\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
6
|
|
\f[R]
|
|
.fi
|
|
.SS Minimum string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foo
|
|
- bar
|
|
- baz
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]min\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bar
|
|
\f[R]
|
|
.fi
|
|
.SS Minimum of empty
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]min\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\f[R]
|
|
.fi
|
|
.SH Modulo
|
|
.PP
|
|
Arithmetic modulo operator, returns the remainder from dividing two
|
|
numbers.
|
|
.SS Number modulo - int
|
|
.PP
|
|
If the lhs and rhs are ints then the expression will be calculated with
|
|
ints.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 13
|
|
b: 2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a % .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: 2
|
|
\f[R]
|
|
.fi
|
|
.SS Number modulo - float
|
|
.PP
|
|
If the lhs or rhs are floats then the expression will be calculated with
|
|
floats.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 12
|
|
b: 2.5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a % .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !!float 2
|
|
b: 2.5
|
|
\f[R]
|
|
.fi
|
|
.SS Number modulo - int by zero
|
|
.PP
|
|
If the lhs is an int and rhs is a 0 the result is an error.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1
|
|
b: 0
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a % .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: cannot modulo by 0
|
|
\f[R]
|
|
.fi
|
|
.SS Number modulo - float by zero
|
|
.PP
|
|
If the lhs is a float and rhs is a 0 the result is NaN.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 1.1
|
|
b: 0
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a % .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !!float NaN
|
|
b: 0
|
|
\f[R]
|
|
.fi
|
|
.SH Multiply (Merge)
|
|
.PP
|
|
Like the multiple operator in jq, depending on the operands, this
|
|
multiply operator will do different things.
|
|
Currently numbers, arrays and objects are supported.
|
|
.SS Objects and arrays - merging
|
|
.PP
|
|
Objects are merged \f[I]deeply\f[R] matching on matching keys.
|
|
By default, array values override and are not deeply merged.
|
|
.PP
|
|
You can use the add operator \f[C]+\f[R], to shallow merge objects, see
|
|
more info here (https://mikefarah.gitbook.io/yq/operators/add).
|
|
.PP
|
|
Note that when merging objects, this operator returns the merged object
|
|
(not the parent).
|
|
This will be clearer in the examples below.
|
|
.SS Merge Flags
|
|
.PP
|
|
You can control how objects are merged by using one or more of the
|
|
following flags.
|
|
Multiple flags can be used together, e.g.\ \f[C].a *+? .b\f[R].
|
|
See examples below
|
|
.IP \[bu] 2
|
|
\f[C]+\f[R] append arrays
|
|
.IP \[bu] 2
|
|
\f[C]d\f[R] deeply merge arrays
|
|
.IP \[bu] 2
|
|
\f[C]?\f[R] only merge \f[I]existing\f[R] fields
|
|
.IP \[bu] 2
|
|
\f[C]n\f[R] only merge \f[I]new\f[R] fields
|
|
.IP \[bu] 2
|
|
\f[C]c\f[R] clobber custom tags
|
|
.PP
|
|
To perform a shallow merge only, use the add operator \f[C]+\f[R], see
|
|
more info here (https://mikefarah.gitbook.io/yq/operators/add).
|
|
.SS Merge two files together
|
|
.PP
|
|
This uses the load operator to merge file2 into file1.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. *= load(\[dq]file2.yml\[dq])\[aq] file1.yml
|
|
\f[R]
|
|
.fi
|
|
.SS Merging all files
|
|
.PP
|
|
Note the use of \f[C]eval-all\f[R] to ensure all documents are loaded
|
|
into memory.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq eval-all \[aq]. as $item ireduce ({}; . * $item )\[aq] *.yml
|
|
\f[R]
|
|
.fi
|
|
.SH Merging complex arrays together by a key field
|
|
.PP
|
|
By default - \f[C]yq\f[R] merge is naive.
|
|
It merges maps when they match the key name, and arrays are merged
|
|
either by appending them together, or merging the entries by their
|
|
position in the array.
|
|
.PP
|
|
For more complex array merging (e.g.\ merging items that match on a
|
|
certain key) please see the example
|
|
here (https://mikefarah.gitbook.io/yq/operators/multiply-merge#merge-arrays-of-objects-together-matching-on-a-key)
|
|
.SS Multiply integers
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 3
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a *= .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 12
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.SS Multiply string node X int
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: banana
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b * 4\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bananabananabananabanana
|
|
\f[R]
|
|
.fi
|
|
.SS Multiply int X string node
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: banana
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]4 * .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bananabananabananabanana
|
|
\f[R]
|
|
.fi
|
|
.SS Multiply string X int node
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
n: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]\[dq]banana\[dq] * .n\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bananabananabananabanana
|
|
\f[R]
|
|
.fi
|
|
.SS Multiply int node X string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
n: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].n * \[dq]banana\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bananabananabananabanana
|
|
\f[R]
|
|
.fi
|
|
.SS Merge objects together, returning merged result only
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
field: me
|
|
fieldA: cat
|
|
b:
|
|
field:
|
|
g: wizz
|
|
fieldB: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a * .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
field:
|
|
g: wizz
|
|
fieldA: cat
|
|
fieldB: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Merge objects together, returning parent object
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
field: me
|
|
fieldA: cat
|
|
b:
|
|
field:
|
|
g: wizz
|
|
fieldB: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. * {\[dq]a\[dq]:.b}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
field:
|
|
g: wizz
|
|
fieldA: cat
|
|
fieldB: dog
|
|
b:
|
|
field:
|
|
g: wizz
|
|
fieldB: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Merge keeps style of LHS
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: {things: great}
|
|
b:
|
|
also: \[dq]me\[dq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. * {\[dq]a\[dq]:.b}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: {things: great, also: \[dq]me\[dq]}
|
|
b:
|
|
also: \[dq]me\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Merge arrays
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
b:
|
|
- 3
|
|
- 4
|
|
- 5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. * {\[dq]a\[dq]:.b}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- 3
|
|
- 4
|
|
- 5
|
|
b:
|
|
- 3
|
|
- 4
|
|
- 5
|
|
\f[R]
|
|
.fi
|
|
.SS Merge, only existing fields
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
thing: one
|
|
cat: frog
|
|
b:
|
|
missing: two
|
|
thing: two
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a *? .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
thing: two
|
|
cat: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Merge, only new fields
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
thing: one
|
|
cat: frog
|
|
b:
|
|
missing: two
|
|
thing: two
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a *n .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
thing: one
|
|
cat: frog
|
|
missing: two
|
|
\f[R]
|
|
.fi
|
|
.SS Merge, appending arrays
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
array:
|
|
- 1
|
|
- 2
|
|
- animal: dog
|
|
value: coconut
|
|
b:
|
|
array:
|
|
- 3
|
|
- 4
|
|
- animal: cat
|
|
value: banana
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a *+ .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
array:
|
|
- 1
|
|
- 2
|
|
- animal: dog
|
|
- 3
|
|
- 4
|
|
- animal: cat
|
|
value: banana
|
|
\f[R]
|
|
.fi
|
|
.SS Merge, only existing fields, appending arrays
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
thing:
|
|
- 1
|
|
- 2
|
|
b:
|
|
thing:
|
|
- 3
|
|
- 4
|
|
another:
|
|
- 1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a *?+ .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
thing:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
- 4
|
|
\f[R]
|
|
.fi
|
|
.SS Merge, deeply merging arrays
|
|
.PP
|
|
Merging arrays deeply means arrays are merged like objects, with indices
|
|
as their key.
|
|
In this case, we merge the first item in the array and do nothing with
|
|
the second.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- name: fred
|
|
age: 12
|
|
- name: bob
|
|
age: 32
|
|
b:
|
|
- name: fred
|
|
age: 34
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a *d .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: fred
|
|
age: 34
|
|
- name: bob
|
|
age: 32
|
|
\f[R]
|
|
.fi
|
|
.SS Merge arrays of objects together, matching on a key
|
|
.PP
|
|
This is a fairly complex expression - you can use it as is by providing
|
|
the environment variables as seen in the example below.
|
|
.PP
|
|
It merges in the array provided in the second file into the first -
|
|
matching on equal keys.
|
|
.PP
|
|
Explanation:
|
|
.PP
|
|
The approach, at a high level, is to reduce into a merged map (keyed by
|
|
the unique key) and then convert that back into an array.
|
|
.PP
|
|
First the expression will create a map from the arrays keyed by the
|
|
idPath, the unique field we want to merge by.
|
|
The reduce operator is merging `({}; . * $item )', so array elements
|
|
with the matching key will be merged together.
|
|
.PP
|
|
Next, we convert the map back to an array, using reduce again,
|
|
concatenating all the map values together.
|
|
.PP
|
|
Finally, we set the result of the merged array back into the first doc.
|
|
.PP
|
|
Thanks Kev from
|
|
stackoverflow (https://stackoverflow.com/a/70109529/1168223)
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myArray:
|
|
- a: apple
|
|
b: appleB
|
|
- a: kiwi
|
|
b: kiwiB
|
|
- a: banana
|
|
b: bananaB
|
|
something: else
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
And another sample another.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
newArray:
|
|
- a: banana
|
|
c: bananaC
|
|
- a: apple
|
|
b: appleB2
|
|
- a: dingo
|
|
c: dingoC
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
idPath=\[dq].a\[dq] originalPath=\[dq].myArray\[dq] otherPath=\[dq].newArray\[dq] yq eval-all \[aq]
|
|
(
|
|
(( (eval(strenv(originalPath)) + eval(strenv(otherPath))) | .[] | {(eval(strenv(idPath))): .}) as $item ireduce ({}; . * $item )) as $uniqueMap
|
|
| ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value)
|
|
) as $mergedArray
|
|
| select(fi == 0) | (eval(strenv(originalPath))) = $mergedArray
|
|
\[aq] sample.yml another.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myArray:
|
|
- a: apple
|
|
b: appleB2
|
|
- a: kiwi
|
|
b: kiwiB
|
|
- a: banana
|
|
b: bananaB
|
|
c: bananaC
|
|
- a: dingo
|
|
c: dingoC
|
|
something: else
|
|
\f[R]
|
|
.fi
|
|
.SS Merge to prefix an element
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. * {\[dq]a\[dq]: {\[dq]c\[dq]: .a}}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
c: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Merge with simple aliases
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &cat
|
|
c: frog
|
|
b:
|
|
f: *cat
|
|
c:
|
|
g: thongs
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].c * .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
g: thongs
|
|
f: *cat
|
|
\f[R]
|
|
.fi
|
|
.SS Merge copies anchor names
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
c: &cat frog
|
|
b:
|
|
f: *cat
|
|
c:
|
|
g: thongs
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].c * .a\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
g: thongs
|
|
c: &cat frog
|
|
\f[R]
|
|
.fi
|
|
.SS Merge with merge anchors
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].foobar * .foobarList\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
c: foobarList_c
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
thing: foobar_thing
|
|
b: foobarList_b
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types: that are really numbers
|
|
.PP
|
|
When custom tags are encountered, yq will try to decode the underlying
|
|
type.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse 2
|
|
b: !goat 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a * .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse 6
|
|
b: !goat 3
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types: that are really maps
|
|
.PP
|
|
Custom tags will be maintained.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse
|
|
cat: meow
|
|
b: !goat
|
|
dog: woof
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a * .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse
|
|
cat: meow
|
|
dog: woof
|
|
b: !goat
|
|
dog: woof
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types: clobber tags
|
|
.PP
|
|
Use the \f[C]c\f[R] option to clobber custom tags.
|
|
Note that the second tag is now used.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse
|
|
cat: meow
|
|
b: !goat
|
|
dog: woof
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a *=c .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !goat
|
|
cat: meow
|
|
dog: woof
|
|
b: !goat
|
|
dog: woof
|
|
\f[R]
|
|
.fi
|
|
.SS Merging a null with a map
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]null * {\[dq]some\[dq]: \[dq]thing\[dq]}\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
some: thing
|
|
\f[R]
|
|
.fi
|
|
.SS Merging a map with null
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]{\[dq]some\[dq]: \[dq]thing\[dq]} * null\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
some: thing
|
|
\f[R]
|
|
.fi
|
|
.SS Merging a null with an array
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]null * [\[dq]some\[dq]]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- some
|
|
\f[R]
|
|
.fi
|
|
.SS Merging an array with null
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq][\[dq]some\[dq]] * null\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- some
|
|
\f[R]
|
|
.fi
|
|
.SH Omit
|
|
.PP
|
|
Works like \f[C]pick\f[R], but instead you specify the keys/indices that
|
|
you \f[I]don\[cq]t\f[R] want included.
|
|
.SS Omit keys from map
|
|
.PP
|
|
Note that non existent keys are skipped.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myMap:
|
|
cat: meow
|
|
dog: bark
|
|
thing: hamster
|
|
hamster: squeak
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].myMap |= omit([\[dq]hamster\[dq], \[dq]cat\[dq], \[dq]goat\[dq]])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myMap:
|
|
dog: bark
|
|
thing: hamster
|
|
\f[R]
|
|
.fi
|
|
.SS Omit indices from array
|
|
.PP
|
|
Note that non existent indices are skipped.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- leopard
|
|
- lion
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]omit([2, 0, 734, -5])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- leopard
|
|
\f[R]
|
|
.fi
|
|
.SH Parent
|
|
.PP
|
|
Parent simply returns the parent nodes of the matching nodes.
|
|
.SS Simple example
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
nested: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.nested | parent\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
nested: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Parent of nested matches
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
fruit: apple
|
|
name: bob
|
|
b:
|
|
fruit: banana
|
|
name: sam
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. | select(. == \[dq]banana\[dq]) | parent\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
fruit: banana
|
|
name: sam
|
|
\f[R]
|
|
.fi
|
|
.SS Get parent attribute
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
fruit: apple
|
|
name: bob
|
|
b:
|
|
fruit: banana
|
|
name: sam
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. | select(. == \[dq]banana\[dq]) | parent.name\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
sam
|
|
\f[R]
|
|
.fi
|
|
.SS N-th parent
|
|
.PP
|
|
You can optionally supply the number of levels to go up for the parent,
|
|
the default being 1.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
c: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b.c | parent(2)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b:
|
|
c: cat
|
|
\f[R]
|
|
.fi
|
|
.SS N-th parent - another level
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
c: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b.c | parent(3)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b:
|
|
c: cat
|
|
\f[R]
|
|
.fi
|
|
.SS No parent
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]parent\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\f[R]
|
|
.fi
|
|
.SH Path
|
|
.PP
|
|
The \f[C]path\f[R] operator can be used to get the traversal paths of
|
|
matching nodes in an expression.
|
|
The path is returned as an array, which if traversed in order will lead
|
|
to the matching node.
|
|
.PP
|
|
You can get the key/index of matching nodes by using the \f[C]path\f[R]
|
|
operator to return the path array then piping that through
|
|
\f[C].[-1]\f[R] to get the last element of that array, the key.
|
|
.PP
|
|
Use \f[C]setpath\f[R] to set a value to the path array returned by
|
|
\f[C]path\f[R], and similarly \f[C]delpaths\f[R] for an array of path
|
|
arrays.
|
|
.SS Map path
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b | path\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a
|
|
- b
|
|
\f[R]
|
|
.fi
|
|
.SS Get map key
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b | path | .[-1]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b
|
|
\f[R]
|
|
.fi
|
|
.SS Array path
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.[] | select(. == \[dq]dog\[dq]) | path\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a
|
|
- 1
|
|
\f[R]
|
|
.fi
|
|
.SS Get array index
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.[] | select(. == \[dq]dog\[dq]) | path | .[-1]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS Print path and value
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cat
|
|
- dog
|
|
- frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a[] | select(. == \[dq]*og\[dq]) | [{\[dq]path\[dq]:path, \[dq]value\[dq]:.}]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- path:
|
|
- a
|
|
- 1
|
|
value: dog
|
|
- path:
|
|
- a
|
|
- 2
|
|
value: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Set path
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]setpath([\[dq]a\[dq], \[dq]b\[dq]]; \[dq]things\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: things
|
|
\f[R]
|
|
.fi
|
|
.SS Set on empty document
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]setpath([\[dq]a\[dq], \[dq]b\[dq]]; \[dq]things\[dq])\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: things
|
|
\f[R]
|
|
.fi
|
|
.SS Set path to prune deep paths
|
|
.PP
|
|
Like pick but recursive.
|
|
This uses \f[C]ireduce\f[R] to deeply set the selected paths into an
|
|
empty object.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
parentA: bob
|
|
parentB:
|
|
child1: i am child1
|
|
child2: i am child2
|
|
parentC:
|
|
child1: me child1
|
|
child2: me child2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.parentB.child2, .parentC.child1) as $i
|
|
ireduce({}; setpath($i | path; $i))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
parentB:
|
|
child2: i am child2
|
|
parentC:
|
|
child1: me child1
|
|
\f[R]
|
|
.fi
|
|
.SS Set array path
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cat
|
|
- frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]setpath([\[dq]a\[dq], 0]; \[dq]things\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- things
|
|
- frog
|
|
\f[R]
|
|
.fi
|
|
.SS Set array path empty
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]setpath([\[dq]a\[dq], 0]; \[dq]things\[dq])\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- things
|
|
\f[R]
|
|
.fi
|
|
.SS Delete path
|
|
.PP
|
|
Notice delpaths takes an \f[I]array\f[R] of paths.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: cat
|
|
c: dog
|
|
d: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]delpaths([[\[dq]a\[dq], \[dq]c\[dq]], [\[dq]a\[dq], \[dq]d\[dq]]])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Delete array path
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cat
|
|
- frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]delpaths([[\[dq]a\[dq], 0]])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- frog
|
|
\f[R]
|
|
.fi
|
|
.SS Delete - wrong parameter
|
|
.PP
|
|
delpaths does not work with a single path array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- cat
|
|
- frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]delpaths([\[dq]a\[dq], 0])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: DELPATHS: expected entry [0] to be a sequence, but its a !!str. Note that delpaths takes an array of path arrays, e.g. [[\[dq]a\[dq], \[dq]b\[dq]]]
|
|
\f[R]
|
|
.fi
|
|
.SH Pick
|
|
.PP
|
|
Filter a map by the specified list of keys.
|
|
Map is returned with the key in the order of the pick list.
|
|
.PP
|
|
Similarly, filter an array by the specified list of indices.
|
|
.SS Pick keys from map
|
|
.PP
|
|
Note that the order of the keys matches the pick order and non existent
|
|
keys are skipped.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myMap:
|
|
cat: meow
|
|
dog: bark
|
|
thing: hamster
|
|
hamster: squeak
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].myMap |= pick([\[dq]hamster\[dq], \[dq]cat\[dq], \[dq]goat\[dq]])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myMap:
|
|
hamster: squeak
|
|
cat: meow
|
|
\f[R]
|
|
.fi
|
|
.SS Pick keys from map, included all the keys
|
|
.PP
|
|
We create a map of the picked keys plus all the current keys, and run
|
|
that through unique
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myMap:
|
|
cat: meow
|
|
dog: bark
|
|
thing: hamster
|
|
hamster: squeak
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].myMap |= pick( ([\[dq]thing\[dq]] + keys) | unique)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myMap:
|
|
thing: hamster
|
|
cat: meow
|
|
dog: bark
|
|
hamster: squeak
|
|
\f[R]
|
|
.fi
|
|
.SS Pick indices from array
|
|
.PP
|
|
Note that the order of the indices matches the pick order and non
|
|
existent indices are skipped.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- leopard
|
|
- lion
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]pick([2, 0, 734, -5])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- lion
|
|
- cat
|
|
\f[R]
|
|
.fi
|
|
.SH Pipe
|
|
.PP
|
|
Pipe the results of an expression into another.
|
|
Like the bash operator.
|
|
.SS Simple Pipe
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a | .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.SS Multiple updates
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cow
|
|
b: sheep
|
|
c: same
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = \[dq]cat\[dq] | .b = \[dq]dog\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
c: same
|
|
\f[R]
|
|
.fi
|
|
.SH Pivot
|
|
.PP
|
|
Emulates the \f[C]PIVOT\f[R] function supported by several popular RDBMS
|
|
systems.
|
|
.SS Pivot a sequence of sequences
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - foo
|
|
- bar
|
|
- baz
|
|
- - sis
|
|
- boom
|
|
- bah
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]pivot\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - foo
|
|
- sis
|
|
- - bar
|
|
- boom
|
|
- - baz
|
|
- bah
|
|
\f[R]
|
|
.fi
|
|
.SS Pivot sequence of heterogeneous sequences
|
|
.PP
|
|
Missing values are \[lq]padded\[rq] to null.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - foo
|
|
- bar
|
|
- baz
|
|
- - sis
|
|
- boom
|
|
- bah
|
|
- blah
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]pivot\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - foo
|
|
- sis
|
|
- - bar
|
|
- boom
|
|
- - baz
|
|
- bah
|
|
- -
|
|
- blah
|
|
\f[R]
|
|
.fi
|
|
.SS Pivot sequence of maps
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foo: a
|
|
bar: b
|
|
baz: c
|
|
- foo: x
|
|
bar: y
|
|
baz: z
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]pivot\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo:
|
|
- a
|
|
- x
|
|
bar:
|
|
- b
|
|
- y
|
|
baz:
|
|
- c
|
|
- z
|
|
\f[R]
|
|
.fi
|
|
.SS Pivot sequence of heterogeneous maps
|
|
.PP
|
|
Missing values are \[lq]padded\[rq] to null.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- foo: a
|
|
bar: b
|
|
baz: c
|
|
- foo: x
|
|
bar: y
|
|
baz: z
|
|
what: ever
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]pivot\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo:
|
|
- a
|
|
- x
|
|
bar:
|
|
- b
|
|
- y
|
|
baz:
|
|
- c
|
|
- z
|
|
what:
|
|
-
|
|
- ever
|
|
\f[R]
|
|
.fi
|
|
.SH Recursive Descent (Glob)
|
|
.PP
|
|
This operator recursively matches (or globs) all children nodes given of
|
|
a particular element, including that node itself.
|
|
This is most often used to apply a filter recursively against all
|
|
matches.
|
|
.SS match values form \f[C]..\f[R]
|
|
.PP
|
|
This will, like the \f[C]jq\f[R] equivalent, recursively match all
|
|
\f[I]value\f[R] nodes.
|
|
Use it to find/manipulate particular values.
|
|
.PP
|
|
For instance to set the \f[C]style\f[R] of all \f[I]value\f[R] nodes in
|
|
a yaml doc, excluding map keys:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. style= \[dq]flow\[dq]\[aq] file.yaml
|
|
\f[R]
|
|
.fi
|
|
.SS match values and map keys form \f[C]...\f[R]
|
|
.PP
|
|
The also includes map keys in the results set.
|
|
This is particularly useful in YAML as unlike JSON, map keys can have
|
|
their own styling and tags and also use anchors and aliases.
|
|
.PP
|
|
For instance to set the \f[C]style\f[R] of all nodes in a yaml doc,
|
|
including the map keys:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]... style= \[dq]flow\[dq]\[aq] file.yaml
|
|
\f[R]
|
|
.fi
|
|
.SS Recurse map (values only)
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]..\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
frog
|
|
\f[R]
|
|
.fi
|
|
.SS Recursively find nodes with keys
|
|
.PP
|
|
Note that this example has wrapped the expression in \f[C][]\f[R] to
|
|
show that there are two matches returned.
|
|
You do not have to wrap in \f[C][]\f[R] in your path expression.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
name: frog
|
|
b:
|
|
name: blog
|
|
age: 12
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][.. | select(has(\[dq]name\[dq]))]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: frog
|
|
b:
|
|
name: blog
|
|
age: 12
|
|
- name: blog
|
|
age: 12
|
|
\f[R]
|
|
.fi
|
|
.SS Recursively find nodes with values
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
nameA: frog
|
|
b:
|
|
nameB: frog
|
|
age: 12
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. | select(. == \[dq]frog\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
frog
|
|
frog
|
|
\f[R]
|
|
.fi
|
|
.SS Recurse map (values and keys)
|
|
.PP
|
|
Note that the map key appears in the results
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]...\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: frog
|
|
a
|
|
frog
|
|
\f[R]
|
|
.fi
|
|
.SS Aliases are not traversed
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &cat
|
|
c: frog
|
|
b: *cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][..]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: &cat
|
|
c: frog
|
|
b: *cat
|
|
- &cat
|
|
c: frog
|
|
- frog
|
|
- *cat
|
|
\f[R]
|
|
.fi
|
|
.SS Merge docs are not traversed
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].foobar | [..]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
- foobar_c
|
|
- *foo
|
|
- foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.SH Reduce
|
|
.PP
|
|
Reduce is a powerful way to process a collection of data into a new
|
|
form.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<exp> as $<name> ireduce (<init>; <block>)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
e.g.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\&.[] as $item ireduce (0; . + $item)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
On the LHS we are configuring the collection of items that will be
|
|
reduced \f[C]<exp>\f[R] as well as what each element will be called
|
|
\f[C]$<name>\f[R].
|
|
Note that the array has been splatted into its individual elements.
|
|
.PP
|
|
On the RHS there is \f[C]<init>\f[R], the starting value of the
|
|
accumulator and \f[C]<block>\f[R], the expression that will update the
|
|
accumulator for each element in the collection.
|
|
Note that within the block expression, \f[C].\f[R] will evaluate to the
|
|
current value of the accumulator.
|
|
.SS yq vs jq syntax
|
|
.PP
|
|
Reduce syntax in \f[C]yq\f[R] is a little different from \f[C]jq\f[R] -
|
|
as \f[C]yq\f[R] (currently) isn\[cq]t as sophisticated as \f[C]jq\f[R]
|
|
and its only supports infix notation (e.g.\ a + b, where the operator is
|
|
in the middle of the two parameters) - where as \f[C]jq\f[R] uses a mix
|
|
of infix notation with \f[I]prefix\f[R] notation
|
|
(e.g.\ \f[C]reduce a b\f[R] is like writing \f[C]+ a b\f[R]).
|
|
.PP
|
|
To that end, the reduce operator is called \f[C]ireduce\f[R] for
|
|
backwards compatibility if a \f[C]jq\f[R] like prefix version of
|
|
\f[C]reduce\f[R] is ever added.
|
|
.SS Sum numbers
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 10
|
|
- 2
|
|
- 5
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] as $item ireduce (0; . + $item)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
20
|
|
\f[R]
|
|
.fi
|
|
.SS Merge all yaml files together
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
And another sample another.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq eval-all \[aq]. as $item ireduce ({}; . * $item )\[aq] sample.yml another.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Convert an array to an object
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Cathy
|
|
has: apples
|
|
- name: Bob
|
|
has: bananas
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] as $item ireduce ({}; .[$item | .name] = ($item | .has) )\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Cathy: apples
|
|
Bob: bananas
|
|
\f[R]
|
|
.fi
|
|
.SH Reverse
|
|
.PP
|
|
Reverses the order of the items in an array
|
|
.SS Reverse
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]reverse\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 3
|
|
- 2
|
|
- 1
|
|
\f[R]
|
|
.fi
|
|
.SS Sort descending by string field
|
|
.PP
|
|
Use sort with reverse to sort in descending order.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: banana
|
|
- a: cat
|
|
- a: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_by(.a) | reverse\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: cat
|
|
- a: banana
|
|
- a: apple
|
|
\f[R]
|
|
.fi
|
|
.SH Select
|
|
.PP
|
|
Select is used to filter arrays and maps by a boolean expression.
|
|
.SS Related Operators
|
|
.IP \[bu] 2
|
|
equals / not equals (\f[C]==\f[R], \f[C]!=\f[R]) operators
|
|
here (https://mikefarah.gitbook.io/yq/operators/equals)
|
|
.IP \[bu] 2
|
|
comparison (\f[C]>=\f[R], \f[C]<\f[R] etc) operators
|
|
here (https://mikefarah.gitbook.io/yq/operators/compare)
|
|
.IP \[bu] 2
|
|
boolean operators (\f[C]and\f[R], \f[C]or\f[R], \f[C]any\f[R] etc)
|
|
here (https://mikefarah.gitbook.io/yq/operators/boolean-operators)
|
|
.SS Select elements from array using wildcard prefix
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- goat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | select(. == \[dq]*at\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
goat
|
|
\f[R]
|
|
.fi
|
|
.SS Select elements from array using wildcard suffix
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- go-kart
|
|
- goat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | select(. == \[dq]go*\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
go-kart
|
|
goat
|
|
\f[R]
|
|
.fi
|
|
.SS Select elements from array using wildcard prefix and suffix
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- ago
|
|
- go
|
|
- meow
|
|
- going
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | select(. == \[dq]*go*\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
ago
|
|
go
|
|
going
|
|
\f[R]
|
|
.fi
|
|
.SS Select elements from array with regular expression
|
|
.PP
|
|
See more regular expression examples under the \f[C]string\f[R] operator
|
|
docs (https://mikefarah.gitbook.io/yq/operators/string-operators).
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- this_0
|
|
- not_this
|
|
- nor_0_this
|
|
- thisTo_4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | select(test(\[dq][a-zA-Z]+_[0-9]$\[dq]))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
this_0
|
|
thisTo_4
|
|
\f[R]
|
|
.fi
|
|
.SS Select items from a map
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
things: cat
|
|
bob: goat
|
|
horse: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | select(. == \[dq]cat\[dq] or test(\[dq]og$\[dq]))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
dog
|
|
\f[R]
|
|
.fi
|
|
.SS Use select and with_entries to filter map keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: bob
|
|
legs: 2
|
|
game: poker
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_entries(select(.key | test(\[dq]ame$\[dq])))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: bob
|
|
game: poker
|
|
\f[R]
|
|
.fi
|
|
.SS Select multiple items in a map and update
|
|
.PP
|
|
Note the brackets around the entire LHS.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
things: cat
|
|
bob: goat
|
|
horse: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.a.[] | select(. == \[dq]cat\[dq] or . == \[dq]goat\[dq])) |= \[dq]rabbit\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
things: rabbit
|
|
bob: rabbit
|
|
horse: dog
|
|
\f[R]
|
|
.fi
|
|
.SH Shuffle
|
|
.PP
|
|
Shuffles an array.
|
|
Note that this command does \f[I]not\f[R] use a cryptographically secure
|
|
random number generator to randomise the array order.
|
|
.SS Shuffle array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
- 4
|
|
- 5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]shuffle\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 5
|
|
- 2
|
|
- 4
|
|
- 1
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.SS Shuffle array in place
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
- 4
|
|
- 5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].cool |= shuffle\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool:
|
|
- 5
|
|
- 2
|
|
- 4
|
|
- 1
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.SH Slice/Splice Array
|
|
.PP
|
|
The slice array operator takes an array as input and returns a subarray.
|
|
Like the \f[C]jq\f[R] equivalent, \f[C].[10:15]\f[R] will return an
|
|
array of length 5, starting from index 10 inclusive, up to index 15
|
|
exclusive.
|
|
Negative numbers count backwards from the end of the array.
|
|
.PP
|
|
You may leave out the first or second number, which will refer to the
|
|
start or end of the array respectively.
|
|
.SS Slicing arrays
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
- frog
|
|
- cow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[1:3]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- dog
|
|
- frog
|
|
\f[R]
|
|
.fi
|
|
.SS Slicing arrays - without the first number
|
|
.PP
|
|
Starts from the start of the array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
- frog
|
|
- cow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[:2]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.SS Slicing arrays - without the second number
|
|
.PP
|
|
Finishes at the end of the array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
- frog
|
|
- cow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[2:]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- frog
|
|
- cow
|
|
\f[R]
|
|
.fi
|
|
.SS Slicing arrays - use negative numbers to count backwards from the end
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
- frog
|
|
- cow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[1:-1]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- dog
|
|
- frog
|
|
\f[R]
|
|
.fi
|
|
.SS Inserting into the middle of an array
|
|
.PP
|
|
using an expression to find the index
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
- frog
|
|
- cow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.[] | select(. == \[dq]dog\[dq]) | key + 1) as $pos | .[0:($pos)] + [\[dq]rabbit\[dq]] + .[$pos:]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
- rabbit
|
|
- frog
|
|
- cow
|
|
\f[R]
|
|
.fi
|
|
.SH Sort Keys
|
|
.PP
|
|
The Sort Keys operator sorts maps by their keys (based on their string
|
|
value).
|
|
This operator does not do anything to arrays or scalars (so you can
|
|
easily recursively apply it to all maps).
|
|
.PP
|
|
Sort is particularly useful for diffing two different yaml documents:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -i -P \[aq]sort_keys(..)\[aq] file1.yml
|
|
yq -i -P \[aq]sort_keys(..)\[aq] file2.yml
|
|
diff file1.yml file2.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Note that \f[C]yq\f[R] does not yet consider anchors when sorting by
|
|
keys - this may result in invalid yaml documents if you are using merge
|
|
anchors.
|
|
.PP
|
|
For more advanced sorting, you can use the
|
|
sort_by (https://mikefarah.gitbook.io/yq/operators/sort) function on a
|
|
map, and give it a custom function like
|
|
\f[C]sort_by(key | downcase)\f[R].
|
|
.SS Sort keys of map
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
c: frog
|
|
a: blah
|
|
b: bing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_keys(.)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: blah
|
|
b: bing
|
|
c: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Sort keys recursively
|
|
.PP
|
|
Note the array elements are left unsorted, but maps inside arrays are
|
|
sorted
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bParent:
|
|
c: dog
|
|
array:
|
|
- 3
|
|
- 1
|
|
- 2
|
|
aParent:
|
|
z: donkey
|
|
x:
|
|
- c: yum
|
|
b: delish
|
|
- b: ew
|
|
a: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_keys(..)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
aParent:
|
|
x:
|
|
- b: delish
|
|
c: yum
|
|
- a: apple
|
|
b: ew
|
|
z: donkey
|
|
bParent:
|
|
array:
|
|
- 3
|
|
- 1
|
|
- 2
|
|
c: dog
|
|
\f[R]
|
|
.fi
|
|
.SH Sort
|
|
.PP
|
|
Sorts an array.
|
|
Use \f[C]sort\f[R] to sort an array as is, or \f[C]sort_by(exp)\f[R] to
|
|
sort by a particular expression (e.g.\ subfield).
|
|
.PP
|
|
To sort by descending order, pipe the results through the
|
|
\f[C]reverse\f[R] operator after sorting.
|
|
.PP
|
|
Note that at this stage, \f[C]yq\f[R] only sorts scalar fields.
|
|
.SS Sort by string field
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: banana
|
|
- a: cat
|
|
- a: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_by(.a)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: apple
|
|
- a: banana
|
|
- a: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Sort by multiple fields
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: dog
|
|
- a: cat
|
|
b: banana
|
|
- a: cat
|
|
b: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_by(.a, .b)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: cat
|
|
b: apple
|
|
- a: cat
|
|
b: banana
|
|
- a: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Sort descending by string field
|
|
.PP
|
|
Use sort with reverse to sort in descending order.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: banana
|
|
- a: cat
|
|
- a: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_by(.a) | reverse\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: cat
|
|
- a: banana
|
|
- a: apple
|
|
\f[R]
|
|
.fi
|
|
.SS Sort array in place
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool:
|
|
- a: banana
|
|
- a: cat
|
|
- a: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].cool |= sort_by(.a)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool:
|
|
- a: apple
|
|
- a: banana
|
|
- a: cat
|
|
\f[R]
|
|
.fi
|
|
.SS Sort array of objects by key
|
|
.PP
|
|
Note that you can give sort_by complex expressions, not just paths
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool:
|
|
- b: banana
|
|
- a: banana
|
|
- c: banana
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].cool |= sort_by(keys | .[0])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cool:
|
|
- a: banana
|
|
- b: banana
|
|
- c: banana
|
|
\f[R]
|
|
.fi
|
|
.SS Sort a map
|
|
.PP
|
|
Sorting a map, by default this will sort by the values
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
y: b
|
|
z: a
|
|
x: c
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
z: a
|
|
y: b
|
|
x: c
|
|
\f[R]
|
|
.fi
|
|
.SS Sort a map by keys
|
|
.PP
|
|
Use sort_by to sort a map using a custom function
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Y: b
|
|
z: a
|
|
x: c
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_by(key | downcase)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
x: c
|
|
Y: b
|
|
z: a
|
|
\f[R]
|
|
.fi
|
|
.SS Sort is stable
|
|
.PP
|
|
Note the order of the elements in unchanged when equal in sorting.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: banana
|
|
b: 1
|
|
- a: banana
|
|
b: 2
|
|
- a: banana
|
|
b: 3
|
|
- a: banana
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_by(.a)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: banana
|
|
b: 1
|
|
- a: banana
|
|
b: 2
|
|
- a: banana
|
|
b: 3
|
|
- a: banana
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.SS Sort by numeric field
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: 10
|
|
- a: 100
|
|
- a: 1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort_by(.a)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: 1
|
|
- a: 10
|
|
- a: 100
|
|
\f[R]
|
|
.fi
|
|
.SS Sort by custom date field
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: 12-Jun-2011
|
|
- a: 23-Dec-2010
|
|
- a: 10-Aug-2011
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_dtf(\[dq]02-Jan-2006\[dq]; sort_by(.a))\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: 23-Dec-2010
|
|
- a: 12-Jun-2011
|
|
- a: 10-Aug-2011
|
|
\f[R]
|
|
.fi
|
|
.SS Sort, nulls come first
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 8
|
|
- 3
|
|
- null
|
|
- 6
|
|
- true
|
|
- false
|
|
- cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]sort\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- null
|
|
- false
|
|
- true
|
|
- 3
|
|
- 6
|
|
- 8
|
|
- cat
|
|
\f[R]
|
|
.fi
|
|
.SH Split into Documents
|
|
.PP
|
|
This operator splits all matches into separate documents
|
|
.SS Split empty
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]split_doc\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\f[R]
|
|
.fi
|
|
.SS Split array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: cat
|
|
- b: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | split_doc\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
---
|
|
b: dog
|
|
\f[R]
|
|
.fi
|
|
.SH String Operators
|
|
.SS RegEx
|
|
.PP
|
|
This uses Golang\[cq]s native regex functions under the hood - See their
|
|
docs (https://github.com/google/re2/wiki/Syntax) for the supported
|
|
syntax.
|
|
.PP
|
|
Case insensitive tip: prefix the regex with \f[C](?i)\f[R] -
|
|
e.g.\ \f[C]test(\[dq](?i)cats\[dq])\f[R].
|
|
.SS match(regEx)
|
|
.PP
|
|
This operator returns the substring match details of the given regEx.
|
|
.SS capture(regEx)
|
|
.PP
|
|
Capture returns named RegEx capture groups in a map.
|
|
Can be more convenient than \f[C]match\f[R] depending on what you are
|
|
doing.
|
|
.SS test(regEx)
|
|
.PP
|
|
Returns true if the string matches the RegEx, false otherwise.
|
|
.SS sub(regEx, replacement)
|
|
.PP
|
|
Substitutes matched substrings.
|
|
The first parameter is the regEx to match substrings within the original
|
|
string.
|
|
The second parameter specifies what to replace those matches with.
|
|
This can refer to capture groups from the first RegEx.
|
|
.SS String blocks, bash and newlines
|
|
.PP
|
|
Bash is notorious for chomping on precious trailing newline characters,
|
|
making it tricky to set strings with newlines properly.
|
|
In particular, the \f[C]$( exp )\f[R] \f[I]will trim trailing
|
|
newlines\f[R].
|
|
.PP
|
|
For instance to get this yaml:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: |
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Using \f[C]$( exp )\f[R] wont work, as it will trim the trailing
|
|
newline.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
m=$(echo \[dq]cat\[rs]n\[dq]) yq -n \[aq].a = strenv(m)\[aq]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
However, using printf works:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
printf -v m \[dq]cat\[rs]n\[dq] ; m=\[dq]$m\[dq] yq -n \[aq].a = strenv(m)\[aq]
|
|
a: |
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
As well as having multiline expressions:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
m=\[dq]cat
|
|
\[dq] yq -n \[aq].a = strenv(m)\[aq]
|
|
a: |
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
Similarly, if you\[cq]re trying to set the content from a file, and want
|
|
a trailing newline:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
IFS= read -rd \[aq]\[aq] output < <(cat my_file)
|
|
output=$output ./yq \[aq].data.values = strenv(output)\[aq] first.yml
|
|
\f[R]
|
|
.fi
|
|
.SS Interpolation
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
value: things
|
|
another: stuff
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].message = \[dq]I like \[rs](.value) and \[rs](.another)\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
value: things
|
|
another: stuff
|
|
message: I like things and stuff
|
|
\f[R]
|
|
.fi
|
|
.SS Interpolation - not a string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
value:
|
|
an: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].message = \[dq]I like \[rs](.value)\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
value:
|
|
an: apple
|
|
message: \[aq]I like an: apple\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS To up (upper) case
|
|
.PP
|
|
Works with unicode characters
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\['a]gua
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]upcase\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\['A]GUA
|
|
\f[R]
|
|
.fi
|
|
.SS To down (lower) case
|
|
.PP
|
|
Works with unicode characters
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\['A]gUA
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]downcase\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\['a]gua
|
|
\f[R]
|
|
.fi
|
|
.SS Join strings
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- meow
|
|
- 1
|
|
- null
|
|
- true
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]join(\[dq]; \[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat; meow; 1; ; true
|
|
\f[R]
|
|
.fi
|
|
.SS Trim strings
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- \[aq] cat\[aq]
|
|
- \[aq]dog \[aq]
|
|
- \[aq] cow cow \[aq]
|
|
- horse
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | trim\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
dog
|
|
cow cow
|
|
horse
|
|
\f[R]
|
|
.fi
|
|
.SS Match string
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo bar foo
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]match(\[dq]foo\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
string: foo
|
|
offset: 0
|
|
length: 3
|
|
captures: []
|
|
\f[R]
|
|
.fi
|
|
.SS Match string, case insensitive
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo bar FOO
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][match(\[dq](?i)foo\[dq]; \[dq]g\[dq])]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- string: foo
|
|
offset: 0
|
|
length: 3
|
|
captures: []
|
|
- string: FOO
|
|
offset: 8
|
|
length: 3
|
|
captures: []
|
|
\f[R]
|
|
.fi
|
|
.SS Match with global capture group
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
abc abc
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][match(\[dq](ab)(c)\[dq]; \[dq]g\[dq])]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- string: abc
|
|
offset: 0
|
|
length: 3
|
|
captures:
|
|
- string: ab
|
|
offset: 0
|
|
length: 2
|
|
- string: c
|
|
offset: 2
|
|
length: 1
|
|
- string: abc
|
|
offset: 4
|
|
length: 3
|
|
captures:
|
|
- string: ab
|
|
offset: 4
|
|
length: 2
|
|
- string: c
|
|
offset: 6
|
|
length: 1
|
|
\f[R]
|
|
.fi
|
|
.SS Match with named capture groups
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo bar foo foo foo
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][match(\[dq]foo (?P<bar123>bar)? foo\[dq]; \[dq]g\[dq])]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- string: foo bar foo
|
|
offset: 0
|
|
length: 11
|
|
captures:
|
|
- string: bar
|
|
offset: 4
|
|
length: 3
|
|
name: bar123
|
|
- string: foo foo
|
|
offset: 12
|
|
length: 8
|
|
captures:
|
|
- string: null
|
|
offset: -1
|
|
length: 0
|
|
name: bar123
|
|
\f[R]
|
|
.fi
|
|
.SS Capture named groups into a map
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
xyzzy-14
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]capture(\[dq](?P<a>[a-z]+)-(?P<n>[0-9]+)\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: xyzzy
|
|
n: \[dq]14\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Match without global flag
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]match(\[dq]cat\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
string: cat
|
|
offset: 0
|
|
length: 3
|
|
captures: []
|
|
\f[R]
|
|
.fi
|
|
.SS Match with global flag
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][match(\[dq]cat\[dq]; \[dq]g\[dq])]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- string: cat
|
|
offset: 0
|
|
length: 3
|
|
captures: []
|
|
- string: cat
|
|
offset: 4
|
|
length: 3
|
|
captures: []
|
|
\f[R]
|
|
.fi
|
|
.SS Test using regex
|
|
.PP
|
|
Like jq\[cq]s equivalent, this works like match but only returns
|
|
true/false instead of full match details
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | test(\[dq]at\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
true
|
|
false
|
|
\f[R]
|
|
.fi
|
|
.SS Substitute / Replace string
|
|
.PP
|
|
This uses Golang\[cq]s regex, described
|
|
here (https://github.com/google/re2/wiki/Syntax).
|
|
Note the use of \f[C]|=\f[R] to run in context of the current string
|
|
value.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: dogs are great
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a |= sub(\[dq]dogs\[dq], \[dq]cats\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cats are great
|
|
\f[R]
|
|
.fi
|
|
.SS Substitute / Replace string with regex
|
|
.PP
|
|
This uses Golang\[cq]s regex, described
|
|
here (https://github.com/google/re2/wiki/Syntax).
|
|
Note the use of \f[C]|=\f[R] to run in context of the current string
|
|
value.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: heat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] |= sub(\[dq](a)\[dq], \[dq]${1}r\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cart
|
|
b: heart
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types: that are really strings
|
|
.PP
|
|
When custom tags are encountered, yq will try to decode the underlying
|
|
type.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse cat
|
|
b: !goat heat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] |= sub(\[dq](a)\[dq], \[dq]${1}r\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse cart
|
|
b: !goat heart
|
|
\f[R]
|
|
.fi
|
|
.SS Split strings
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat; meow; 1; ; true
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]split(\[dq]; \[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- meow
|
|
- \[dq]1\[dq]
|
|
- \[dq]\[dq]
|
|
- \[dq]true\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Split strings one match
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
word
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]split(\[dq]; \[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- word
|
|
\f[R]
|
|
.fi
|
|
.SS To string
|
|
.PP
|
|
Note that you may want to force \f[C]yq\f[R] to leave scalar values
|
|
wrapped by passing in \f[C]--unwrapScalar=false\f[R] or \f[C]-r=f\f[R]
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- true
|
|
- null
|
|
- \[ti]
|
|
- cat
|
|
- an: object
|
|
- - array
|
|
- 2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] |= to_string\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- \[dq]1\[dq]
|
|
- \[dq]true\[dq]
|
|
- \[dq]null\[dq]
|
|
- \[dq]\[ti]\[dq]
|
|
- cat
|
|
- \[dq]an: object\[dq]
|
|
- \[dq]- array\[rs]n- 2\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SH Style
|
|
.PP
|
|
The style operator can be used to get or set the style of nodes
|
|
(e.g.\ string style, yaml style).
|
|
Use this to control the formatting of the document in yaml.
|
|
.SS Update and set style of a particular node (simple)
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: thing
|
|
c: something
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b = \[dq]new\[dq] | .a.b style=\[dq]double\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: \[dq]new\[dq]
|
|
c: something
|
|
\f[R]
|
|
.fi
|
|
.SS Update and set style of a particular node using path variables
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: thing
|
|
c: something
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with(.a.b ; . = \[dq]new\[dq] | . style=\[dq]double\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: \[dq]new\[dq]
|
|
c: something
|
|
\f[R]
|
|
.fi
|
|
.SS Set tagged style
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
g:
|
|
something: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. style=\[dq]tagged\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
!!map
|
|
a: !!str cat
|
|
b: !!int 5
|
|
c: !!float 3.2
|
|
e: !!bool true
|
|
f: !!seq
|
|
- !!int 1
|
|
- !!int 2
|
|
- !!int 3
|
|
g: !!map
|
|
something: !!str cool
|
|
\f[R]
|
|
.fi
|
|
.SS Set double quote style
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
g:
|
|
something: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. style=\[dq]double\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[dq]cat\[dq]
|
|
b: \[dq]5\[dq]
|
|
c: \[dq]3.2\[dq]
|
|
e: \[dq]true\[dq]
|
|
f:
|
|
- \[dq]1\[dq]
|
|
- \[dq]2\[dq]
|
|
- \[dq]3\[dq]
|
|
g:
|
|
something: \[dq]cool\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Set double quote style on map keys too
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
g:
|
|
something: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]... style=\[dq]double\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\[dq]a\[dq]: \[dq]cat\[dq]
|
|
\[dq]b\[dq]: \[dq]5\[dq]
|
|
\[dq]c\[dq]: \[dq]3.2\[dq]
|
|
\[dq]e\[dq]: \[dq]true\[dq]
|
|
\[dq]f\[dq]:
|
|
- \[dq]1\[dq]
|
|
- \[dq]2\[dq]
|
|
- \[dq]3\[dq]
|
|
\[dq]g\[dq]:
|
|
\[dq]something\[dq]: \[dq]cool\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Set single quote style
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
g:
|
|
something: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. style=\[dq]single\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[aq]cat\[aq]
|
|
b: \[aq]5\[aq]
|
|
c: \[aq]3.2\[aq]
|
|
e: \[aq]true\[aq]
|
|
f:
|
|
- \[aq]1\[aq]
|
|
- \[aq]2\[aq]
|
|
- \[aq]3\[aq]
|
|
g:
|
|
something: \[aq]cool\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Set literal quote style
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
g:
|
|
something: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. style=\[dq]literal\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: |-
|
|
cat
|
|
b: |-
|
|
5
|
|
c: |-
|
|
3.2
|
|
e: |-
|
|
true
|
|
f:
|
|
- |-
|
|
1
|
|
- |-
|
|
2
|
|
- |-
|
|
3
|
|
g:
|
|
something: |-
|
|
cool
|
|
\f[R]
|
|
.fi
|
|
.SS Set folded quote style
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
g:
|
|
something: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. style=\[dq]folded\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: >-
|
|
cat
|
|
b: >-
|
|
5
|
|
c: >-
|
|
3.2
|
|
e: >-
|
|
true
|
|
f:
|
|
- >-
|
|
1
|
|
- >-
|
|
2
|
|
- >-
|
|
3
|
|
g:
|
|
something: >-
|
|
cool
|
|
\f[R]
|
|
.fi
|
|
.SS Set flow quote style
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
g:
|
|
something: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. style=\[dq]flow\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{a: cat, b: 5, c: 3.2, e: true, f: [1, 2, 3], g: {something: cool}}
|
|
\f[R]
|
|
.fi
|
|
.SS Reset style - or pretty print
|
|
.PP
|
|
Set empty (default) quote style, note the usage of \f[C]...\f[R] to
|
|
match keys too.
|
|
Note that there is a \f[C]--prettyPrint/-P\f[R] short flag for this.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{a: cat, \[dq]b\[dq]: 5, \[aq]c\[aq]: 3.2, \[dq]e\[dq]: true, f: [1,2,3], \[dq]g\[dq]: { something: \[dq]cool\[dq]} }
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]... style=\[dq]\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f:
|
|
- 1
|
|
- 2
|
|
- 3
|
|
g:
|
|
something: cool
|
|
\f[R]
|
|
.fi
|
|
.SS Set style relatively with assign-update
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: single
|
|
b: double
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] style |= .\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: \[aq]single\[aq]
|
|
b: \[dq]double\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Read style
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{a: \[dq]cat\[dq], b: \[aq]thing\[aq]}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. | style\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
flow
|
|
double
|
|
single
|
|
\f[R]
|
|
.fi
|
|
.SH Subtract
|
|
.PP
|
|
You can use subtract to subtract numbers as well as remove elements from
|
|
an array.
|
|
.SS Array subtraction
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq][1,2] - [2,3]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
\f[R]
|
|
.fi
|
|
.SS Array subtraction with nested array
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq][[1], 1, 2] - [[1], 3]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
\f[R]
|
|
.fi
|
|
.SS Array subtraction with nested object
|
|
.PP
|
|
Note that order of the keys does not matter
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: b
|
|
c: d
|
|
- a: b
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]. - [{\[dq]c\[dq]: \[dq]d\[dq], \[dq]a\[dq]: \[dq]b\[dq]}]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- a: b
|
|
\f[R]
|
|
.fi
|
|
.SS Number subtraction - float
|
|
.PP
|
|
If the lhs or rhs are floats then the expression will be calculated with
|
|
floats.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 3
|
|
b: 4.5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a - .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: -1.5
|
|
b: 4.5
|
|
\f[R]
|
|
.fi
|
|
.SS Number subtraction - int
|
|
.PP
|
|
If both the lhs and rhs are ints then the expression will be calculated
|
|
with ints.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 3
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a = .a - .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: -1
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.SS Decrement numbers
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 3
|
|
b: 5
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] -= 1\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2
|
|
b: 4
|
|
\f[R]
|
|
.fi
|
|
.SS Date subtraction
|
|
.PP
|
|
You can subtract durations from dates.
|
|
Assumes RFC3339 date time format, see date-time
|
|
operators (https://mikefarah.gitbook.io/yq/operators/date-time-operators)
|
|
for more information.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T03:10:00Z
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a -= \[dq]3h10m\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: 2021-01-01T00:00:00Z
|
|
\f[R]
|
|
.fi
|
|
.SS Date subtraction - custom format
|
|
.PP
|
|
Use with_dtf to specify your datetime format.
|
|
See date-time
|
|
operators (https://mikefarah.gitbook.io/yq/operators/date-time-operators)
|
|
for more information.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 6:00AM GMT
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with_dtf(\[dq]Monday, 02-Jan-06 at 3:04PM MST\[dq], .a -= \[dq]3h1m\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Saturday, 15-Dec-01 at 2:59AM GMT
|
|
\f[R]
|
|
.fi
|
|
.SS Custom types: that are really numbers
|
|
.PP
|
|
When custom tags are encountered, yq will try to decode the underlying
|
|
type.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse 2
|
|
b: !goat 1
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a -= .b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !horse 1
|
|
b: !goat 1
|
|
\f[R]
|
|
.fi
|
|
.SH Tag
|
|
.PP
|
|
The tag operator can be used to get or set the tag of nodes
|
|
(e.g.\ \f[C]!!str\f[R], \f[C]!!int\f[R], \f[C]!!bool\f[R]).
|
|
.SS Get tag
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f: []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. | tag\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
!!map
|
|
!!str
|
|
!!int
|
|
!!float
|
|
!!bool
|
|
!!seq
|
|
\f[R]
|
|
.fi
|
|
.SS type is an alias for tag
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
f: []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. | type\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
!!map
|
|
!!str
|
|
!!int
|
|
!!float
|
|
!!bool
|
|
!!seq
|
|
\f[R]
|
|
.fi
|
|
.SS Set custom tag
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: str
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a tag = \[dq]!!mikefarah\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: !!mikefarah str
|
|
\f[R]
|
|
.fi
|
|
.SS Find numbers and convert them to strings
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: 5
|
|
c: 3.2
|
|
e: true
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.. | select(tag == \[dq]!!int\[dq])) tag= \[dq]!!str\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
b: \[dq]5\[dq]
|
|
c: 3.2
|
|
e: true
|
|
\f[R]
|
|
.fi
|
|
.SH To Number
|
|
.PP
|
|
Parses the input as a number.
|
|
yq will try to parse values as an int first, failing that it will try
|
|
float.
|
|
Values that already ints or floats will be left alone.
|
|
.SS Converts strings to numbers
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- \[dq]3\[dq]
|
|
- \[dq]3.1\[dq]
|
|
- \[dq]-1e3\[dq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | to_number\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
3
|
|
3.1
|
|
-1e3
|
|
\f[R]
|
|
.fi
|
|
.SS Doesn\[cq]t change numbers
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 3
|
|
- 3.1
|
|
- -1e3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | to_number\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
3
|
|
3.1
|
|
-1e3
|
|
\f[R]
|
|
.fi
|
|
.SS Cannot convert null
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq].a.b | to_number\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Error: cannot convert node value [null] at path a.b of tag !!null to number
|
|
\f[R]
|
|
.fi
|
|
.SH Traverse (Read)
|
|
.PP
|
|
This is the simplest (and perhaps most used) operator.
|
|
It is used to navigate deeply into yaml structures.
|
|
.SS Simple map navigation
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: apple
|
|
\f[R]
|
|
.fi
|
|
.SS Splat
|
|
.PP
|
|
Often used to pipe children into other operators
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- b: apple
|
|
- c: banana
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: apple
|
|
c: banana
|
|
\f[R]
|
|
.fi
|
|
.SS Optional Splat
|
|
.PP
|
|
Just like splat, but won\[cq]t error if you run it against scalars
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\f[R]
|
|
.fi
|
|
.SS Special characters
|
|
.PP
|
|
Use quotes with square brackets around path elements with special
|
|
characters
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\[dq]{}\[dq]: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[\[dq]{}\[dq]]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
frog
|
|
\f[R]
|
|
.fi
|
|
.SS Nested special characters
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
\[dq]key.withdots\[dq]:
|
|
\[dq]another.key\[dq]: apple
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a[\[dq]key.withdots\[dq]][\[dq]another.key\[dq]]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
apple
|
|
\f[R]
|
|
.fi
|
|
.SS Keys with spaces
|
|
.PP
|
|
Use quotes with square brackets around path elements with special
|
|
characters
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\[dq]red rabbit\[dq]: frog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[\[dq]red rabbit\[dq]]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
frog
|
|
\f[R]
|
|
.fi
|
|
.SS Dynamic keys
|
|
.PP
|
|
Expressions within [] can be used to dynamically lookup / calculate keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
b: apple
|
|
apple: crispy yum
|
|
banana: soft yum
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[.b]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
crispy yum
|
|
\f[R]
|
|
.fi
|
|
.SS Children don\[cq]t exist
|
|
.PP
|
|
Nodes are added dynamically while traversing
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
c: banana
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
null
|
|
\f[R]
|
|
.fi
|
|
.SS Optional identifier
|
|
.PP
|
|
Like jq, does not output an error when the yaml is not an array or
|
|
object as expected
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a?\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\f[R]
|
|
.fi
|
|
.SS Wildcard matching
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
cat: apple
|
|
mad: things
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.\[dq]*a*\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
apple
|
|
things
|
|
\f[R]
|
|
.fi
|
|
.SS Aliases
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &cat
|
|
c: frog
|
|
b: *cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
*cat
|
|
\f[R]
|
|
.fi
|
|
.SS Traversing aliases with splat
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &cat
|
|
c: frog
|
|
b: *cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b[]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
frog
|
|
\f[R]
|
|
.fi
|
|
.SS Traversing aliases explicitly
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: &cat
|
|
c: frog
|
|
b: *cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].b.c\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
frog
|
|
\f[R]
|
|
.fi
|
|
.SS Traversing arrays by index
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 1
|
|
- 2
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[0]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1
|
|
\f[R]
|
|
.fi
|
|
.SS Traversing nested arrays by index
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[[], [cat]]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[1][0]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.SS Maps with numeric keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
2: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[2]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.SS Maps with non existing numeric keys
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: b
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[0]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
null
|
|
\f[R]
|
|
.fi
|
|
.SS Traversing merge anchors
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].foobar.a\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo_a
|
|
\f[R]
|
|
.fi
|
|
.SS Traversing merge anchors with override
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].foobar.c\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo_c
|
|
\f[R]
|
|
.fi
|
|
.SS Traversing merge anchors with local override
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].foobar.thing\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.SS Splatting merge anchors
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].foobar[]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo_c
|
|
foo_a
|
|
foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.SS Traversing merge anchor lists
|
|
.PP
|
|
Note that the later merge anchors override previous
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].foobarList.thing\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bar_thing
|
|
\f[R]
|
|
.fi
|
|
.SS Splatting merge anchor lists
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
foo: &foo
|
|
a: foo_a
|
|
thing: foo_thing
|
|
c: foo_c
|
|
bar: &bar
|
|
b: bar_b
|
|
thing: bar_thing
|
|
c: bar_c
|
|
foobarList:
|
|
b: foobarList_b
|
|
!!merge <<:
|
|
- *foo
|
|
- *bar
|
|
c: foobarList_c
|
|
foobar:
|
|
c: foobar_c
|
|
!!merge <<: *foo
|
|
thing: foobar_thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].foobarList[]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
bar_b
|
|
foo_a
|
|
bar_thing
|
|
foobarList_c
|
|
\f[R]
|
|
.fi
|
|
.SS Select multiple indices
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
- a
|
|
- b
|
|
- c
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a[0, 2]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a
|
|
c
|
|
\f[R]
|
|
.fi
|
|
.SH Union
|
|
.PP
|
|
This operator is used to combine different results together.
|
|
.SS Combine scalars
|
|
.PP
|
|
Running
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --null-input \[aq]1, true, \[dq]cat\[dq]\[aq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
1
|
|
true
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.SS Combine selected paths
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: fieldA
|
|
b: fieldB
|
|
c: fieldC
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a, .c\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
fieldA
|
|
fieldC
|
|
\f[R]
|
|
.fi
|
|
.SH Unique
|
|
.PP
|
|
This is used to filter out duplicated items in an array.
|
|
Note that the original order of the array is maintained.
|
|
.SS Unique array of scalars (string/numbers)
|
|
.PP
|
|
Note that unique maintains the original order of the array.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 2
|
|
- 1
|
|
- 3
|
|
- 2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]unique\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- 2
|
|
- 1
|
|
- 3
|
|
\f[R]
|
|
.fi
|
|
.SS Unique nulls
|
|
.PP
|
|
Unique works on the node value, so it considers different
|
|
representations of nulls to be different
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- \[ti]
|
|
- null
|
|
- \[ti]
|
|
- null
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]unique\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- \[ti]
|
|
- null
|
|
\f[R]
|
|
.fi
|
|
.SS Unique all nulls
|
|
.PP
|
|
Run against the node tag to unique all the nulls
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- \[ti]
|
|
- null
|
|
- \[ti]
|
|
- null
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]unique_by(tag)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- \[ti]
|
|
\f[R]
|
|
.fi
|
|
.SS Unique array objects
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: harry
|
|
pet: cat
|
|
- name: billy
|
|
pet: dog
|
|
- name: harry
|
|
pet: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]unique\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: harry
|
|
pet: cat
|
|
- name: billy
|
|
pet: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Unique array of objects by a field
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: harry
|
|
pet: cat
|
|
- name: billy
|
|
pet: dog
|
|
- name: harry
|
|
pet: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]unique_by(.name)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: harry
|
|
pet: cat
|
|
- name: billy
|
|
pet: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Unique array of arrays
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - cat
|
|
- dog
|
|
- - cat
|
|
- sheep
|
|
- - cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]unique\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- - cat
|
|
- dog
|
|
- - cat
|
|
- sheep
|
|
\f[R]
|
|
.fi
|
|
.SH Variable Operators
|
|
.PP
|
|
Like the \f[C]jq\f[R] equivalents, variables are sometimes required for
|
|
the more complex expressions (or swapping values between fields).
|
|
.PP
|
|
Note that there is also an additional \f[C]ref\f[R] operator that holds
|
|
a reference (instead of a copy) of the path, allowing you to make
|
|
multiple changes to the same path.
|
|
.SS Single value variable
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a as $foo | $foo\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
\f[R]
|
|
.fi
|
|
.SS Multi value variable
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- cat
|
|
- dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] as $foo | $foo\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat
|
|
dog
|
|
\f[R]
|
|
.fi
|
|
.SS Using variables as a lookup
|
|
.PP
|
|
Example taken from
|
|
jq (https://stedolan.github.io/jq/manual/#Variable/SymbolicBindingOperator:...as$identifier%7C...)
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\[dq]posts\[dq]:
|
|
- \[dq]title\[dq]: First post
|
|
\[dq]author\[dq]: anon
|
|
- \[dq]title\[dq]: A well-written article
|
|
\[dq]author\[dq]: person1
|
|
\[dq]realnames\[dq]:
|
|
\[dq]anon\[dq]: Anonymous Coward
|
|
\[dq]person1\[dq]: Person McPherson
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].realnames as $names | .posts[] | {\[dq]title\[dq]:.title, \[dq]author\[dq]: $names[.author]}\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
title: First post
|
|
author: Anonymous Coward
|
|
title: A well-written article
|
|
author: Person McPherson
|
|
\f[R]
|
|
.fi
|
|
.SS Using variables to swap values
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: a_value
|
|
b: b_value
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a as $x | .b as $y | .b = $x | .a = $y\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: b_value
|
|
b: a_value
|
|
\f[R]
|
|
.fi
|
|
.SS Use ref to reference a path repeatedly
|
|
.PP
|
|
Note: You may find the \f[C]with\f[R] operator more useful.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: thing
|
|
c: something
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].a.b ref $x | $x = \[dq]new\[dq] | $x style=\[dq]double\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: \[dq]new\[dq]
|
|
c: something
|
|
\f[R]
|
|
.fi
|
|
.SH With
|
|
.PP
|
|
Use the \f[C]with\f[R] operator to conveniently make multiple updates to
|
|
a deeply nested path, or to update array elements relatively to each
|
|
other.
|
|
The first argument expression sets the root context, and the second
|
|
expression runs against that root context.
|
|
.SS Update and style
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
deeply:
|
|
nested: value
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with(.a.deeply.nested; . = \[dq]newValue\[dq] | . style=\[dq]single\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
deeply:
|
|
nested: \[aq]newValue\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Update multiple deeply nested properties
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
deeply:
|
|
nested: value
|
|
other: thing
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with(.a.deeply; .nested = \[dq]newValue\[dq] | .other= \[dq]newThing\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
deeply:
|
|
nested: newValue
|
|
other: newThing
|
|
\f[R]
|
|
.fi
|
|
.SS Update array elements relatively
|
|
.PP
|
|
The second expression runs with each element of the array as it\[cq]s
|
|
contextual root.
|
|
This allows you to make updates relative to the element.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myArray:
|
|
- a: apple
|
|
- a: banana
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with(.myArray[]; .b = .a + \[dq] yum\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myArray:
|
|
- a: apple
|
|
b: apple yum
|
|
- a: banana
|
|
b: banana yum
|
|
\f[R]
|
|
.fi
|
|
.SH JSON
|
|
.PP
|
|
Encode and decode to and from JSON.
|
|
Supports multiple JSON documents in a single file (e.g.\ NDJSON).
|
|
.PP
|
|
Note that YAML is a superset of (single document) JSON - so you
|
|
don\[cq]t have to use the JSON parser to read JSON when there is only
|
|
one JSON document in the input.
|
|
You will probably want to pretty print the result in this case, to get
|
|
idiomatic YAML styling.
|
|
.SS Parse json: simple
|
|
.PP
|
|
JSON is a subset of yaml, so all you need to do is prettify the output
|
|
.PP
|
|
Given a sample.json file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]cat\[dq]: \[dq]meow\[dq]}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=json sample.json
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat: meow
|
|
\f[R]
|
|
.fi
|
|
.SS Parse json: complex
|
|
.PP
|
|
JSON is a subset of yaml, so all you need to do is prettify the output
|
|
.PP
|
|
Given a sample.json file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]a\[dq]:\[dq]Easy! as one two three\[dq],\[dq]b\[dq]:{\[dq]c\[dq]:2,\[dq]d\[dq]:[3,4]}}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=json sample.json
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a: Easy! as one two three
|
|
b:
|
|
c: 2
|
|
d:
|
|
- 3
|
|
- 4
|
|
\f[R]
|
|
.fi
|
|
.SS Encode json: simple
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat: meow
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=json \[aq].\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{
|
|
\[dq]cat\[dq]: \[dq]meow\[dq]
|
|
}
|
|
\f[R]
|
|
.fi
|
|
.SS Encode json: simple - in one line
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat: meow # this is a comment, and it will be dropped.
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=json -I=0 \[aq].\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]cat\[dq]:\[dq]meow\[dq]}
|
|
\f[R]
|
|
.fi
|
|
.SS Encode json: comments
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat: meow # this is a comment, and it will be dropped.
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=json \[aq].\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{
|
|
\[dq]cat\[dq]: \[dq]meow\[dq]
|
|
}
|
|
\f[R]
|
|
.fi
|
|
.SS Encode json: anchors
|
|
.PP
|
|
Anchors are dereferenced
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat: &ref meow
|
|
anotherCat: *ref
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=json \[aq].\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{
|
|
\[dq]cat\[dq]: \[dq]meow\[dq],
|
|
\[dq]anotherCat\[dq]: \[dq]meow\[dq]
|
|
}
|
|
\f[R]
|
|
.fi
|
|
.SS Encode json: multiple results
|
|
.PP
|
|
Each matching node is converted into a json doc.
|
|
This is best used with 0 indent (json document per line)
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
things: [{stuff: cool}, {whatever: cat}]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=json -I=0 \[aq].things[]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]stuff\[dq]:\[dq]cool\[dq]}
|
|
{\[dq]whatever\[dq]:\[dq]cat\[dq]}
|
|
\f[R]
|
|
.fi
|
|
.SS Roundtrip JSON Lines / NDJSON
|
|
.PP
|
|
Given a sample.json file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]this\[dq]: \[dq]is a multidoc json file\[dq]}
|
|
{\[dq]each\[dq]: [\[dq]line is a valid json document\[dq]]}
|
|
{\[dq]a number\[dq]: 4}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=json -o=json -I=0 sample.json
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]this\[dq]:\[dq]is a multidoc json file\[dq]}
|
|
{\[dq]each\[dq]:[\[dq]line is a valid json document\[dq]]}
|
|
{\[dq]a number\[dq]:4}
|
|
\f[R]
|
|
.fi
|
|
.SS Roundtrip multi-document JSON
|
|
.PP
|
|
The parser can also handle multiple multi-line json documents in a
|
|
single file (despite this not being in the JSON Lines / NDJSON spec).
|
|
Typically you would have one entire JSON document per line, but the
|
|
parser also supports multiple multi-line json documents
|
|
.PP
|
|
Given a sample.json file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{
|
|
\[dq]this\[dq]: \[dq]is a multidoc json file\[dq]
|
|
}
|
|
{
|
|
\[dq]it\[dq]: [
|
|
\[dq]has\[dq],
|
|
\[dq]consecutive\[dq],
|
|
\[dq]json documents\[dq]
|
|
]
|
|
}
|
|
{
|
|
\[dq]a number\[dq]: 4
|
|
}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=json -o=json -I=2 sample.json
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{
|
|
\[dq]this\[dq]: \[dq]is a multidoc json file\[dq]
|
|
}
|
|
{
|
|
\[dq]it\[dq]: [
|
|
\[dq]has\[dq],
|
|
\[dq]consecutive\[dq],
|
|
\[dq]json documents\[dq]
|
|
]
|
|
}
|
|
{
|
|
\[dq]a number\[dq]: 4
|
|
}
|
|
\f[R]
|
|
.fi
|
|
.SS Update a specific document in a multi-document json
|
|
.PP
|
|
Documents are indexed by the \f[C]documentIndex\f[R] or \f[C]di\f[R]
|
|
operator.
|
|
.PP
|
|
Given a sample.json file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]this\[dq]: \[dq]is a multidoc json file\[dq]}
|
|
{\[dq]each\[dq]: [\[dq]line is a valid json document\[dq]]}
|
|
{\[dq]a number\[dq]: 4}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=json -o=json -I=0 \[aq](select(di == 1) | .each ) += \[dq]cool\[dq]\[aq] sample.json
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]this\[dq]:\[dq]is a multidoc json file\[dq]}
|
|
{\[dq]each\[dq]:[\[dq]line is a valid json document\[dq],\[dq]cool\[dq]]}
|
|
{\[dq]a number\[dq]:4}
|
|
\f[R]
|
|
.fi
|
|
.SS Find and update a specific document in a multi-document json
|
|
.PP
|
|
Use expressions as you normally would.
|
|
.PP
|
|
Given a sample.json file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]this\[dq]: \[dq]is a multidoc json file\[dq]}
|
|
{\[dq]each\[dq]: [\[dq]line is a valid json document\[dq]]}
|
|
{\[dq]a number\[dq]: 4}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=json -o=json -I=0 \[aq](select(has(\[dq]each\[dq])) | .each ) += \[dq]cool\[dq]\[aq] sample.json
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]this\[dq]:\[dq]is a multidoc json file\[dq]}
|
|
{\[dq]each\[dq]:[\[dq]line is a valid json document\[dq],\[dq]cool\[dq]]}
|
|
{\[dq]a number\[dq]:4}
|
|
\f[R]
|
|
.fi
|
|
.SS Decode JSON Lines / NDJSON
|
|
.PP
|
|
Given a sample.json file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{\[dq]this\[dq]: \[dq]is a multidoc json file\[dq]}
|
|
{\[dq]each\[dq]: [\[dq]line is a valid json document\[dq]]}
|
|
{\[dq]a number\[dq]: 4}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=json sample.json
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
this: is a multidoc json file
|
|
---
|
|
each:
|
|
- line is a valid json document
|
|
---
|
|
a number: 4
|
|
\f[R]
|
|
.fi
|
|
.SH CSV
|
|
.PP
|
|
Encode/Decode/Roundtrip CSV and TSV files.
|
|
.SS Encode
|
|
.PP
|
|
Currently supports arrays of homogeneous flat objects, that is: no
|
|
nesting and it assumes the \f[I]first\f[R] object has all the keys
|
|
required:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Bobo
|
|
type: dog
|
|
- name: Fifi
|
|
type: cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
As well as arrays of arrays of scalars (strings/numbers/booleans):
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- [Bobo, dog]
|
|
- [Fifi, cat]
|
|
\f[R]
|
|
.fi
|
|
.SS Decode
|
|
.PP
|
|
Decode assumes the first CSV/TSV row is the header row, and all rows
|
|
beneath are the entries.
|
|
The data will be coded into an array of objects, using the header rows
|
|
as keys.
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name,type
|
|
Bobo,dog
|
|
Fifi,cat
|
|
\f[R]
|
|
.fi
|
|
.SS Encode CSV simple
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- [i, like, csv]
|
|
- [because, excel, is, cool]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=csv sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
i,like,csv
|
|
because,excel,is,cool
|
|
\f[R]
|
|
.fi
|
|
.SS Encode TSV simple
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- [i, like, csv]
|
|
- [because, excel, is, cool]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=tsv sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
i like csv
|
|
because excel is cool
|
|
\f[R]
|
|
.fi
|
|
.SS Encode array of objects to csv
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Gary
|
|
numberOfCats: 1
|
|
likesApples: true
|
|
height: 168.8
|
|
- name: Samantha\[aq]s Rabbit
|
|
numberOfCats: 2
|
|
likesApples: false
|
|
height: -188.8
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=csv sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name,numberOfCats,likesApples,height
|
|
Gary,1,true,168.8
|
|
Samantha\[aq]s Rabbit,2,false,-188.8
|
|
\f[R]
|
|
.fi
|
|
.SS Encode array of objects to custom csv format
|
|
.PP
|
|
Add the header row manually, then the we convert each object into an
|
|
array of values - resulting in an array of arrays.
|
|
Pick the columns and call the header whatever you like.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Gary
|
|
numberOfCats: 1
|
|
likesApples: true
|
|
height: 168.8
|
|
- name: Samantha\[aq]s Rabbit
|
|
numberOfCats: 2
|
|
likesApples: false
|
|
height: -188.8
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=csv \[aq][[\[dq]Name\[dq], \[dq]Number of Cats\[dq]]] + [.[] | [.name, .numberOfCats ]]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
Name,Number of Cats
|
|
Gary,1
|
|
Samantha\[aq]s Rabbit,2
|
|
\f[R]
|
|
.fi
|
|
.SS Encode array of objects to csv - missing fields behaviour
|
|
.PP
|
|
First entry is used to determine the headers, and it is missing
|
|
`likesApples', so it is not included in the csv.
|
|
Second entry does not have `numberOfCats' so that is blank
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Gary
|
|
numberOfCats: 1
|
|
height: 168.8
|
|
- name: Samantha\[aq]s Rabbit
|
|
height: -188.8
|
|
likesApples: false
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=csv sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name,numberOfCats,height
|
|
Gary,1,168.8
|
|
Samantha\[aq]s Rabbit,,-188.8
|
|
\f[R]
|
|
.fi
|
|
.SS Parse CSV into an array of objects
|
|
.PP
|
|
First row is assumed to be the header row.
|
|
By default, entries with YAML/JSON formatting will be parsed!
|
|
.PP
|
|
Given a sample.csv file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name,numberOfCats,likesApples,height,facts
|
|
Gary,1,true,168.8,cool: true
|
|
Samantha\[aq]s Rabbit,2,false,-188.8,tall: indeed
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=csv sample.csv
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Gary
|
|
numberOfCats: 1
|
|
likesApples: true
|
|
height: 168.8
|
|
facts:
|
|
cool: true
|
|
- name: Samantha\[aq]s Rabbit
|
|
numberOfCats: 2
|
|
likesApples: false
|
|
height: -188.8
|
|
facts:
|
|
tall: indeed
|
|
\f[R]
|
|
.fi
|
|
.SS Parse CSV into an array of objects, no auto-parsing
|
|
.PP
|
|
First row is assumed to be the header row.
|
|
Entries with YAML/JSON will be left as strings.
|
|
.PP
|
|
Given a sample.csv file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name,numberOfCats,likesApples,height,facts
|
|
Gary,1,true,168.8,cool: true
|
|
Samantha\[aq]s Rabbit,2,false,-188.8,tall: indeed
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=csv --csv-auto-parse=f sample.csv
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Gary
|
|
numberOfCats: 1
|
|
likesApples: true
|
|
height: 168.8
|
|
facts: \[aq]cool: true\[aq]
|
|
- name: Samantha\[aq]s Rabbit
|
|
numberOfCats: 2
|
|
likesApples: false
|
|
height: -188.8
|
|
facts: \[aq]tall: indeed\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Parse TSV into an array of objects
|
|
.PP
|
|
First row is assumed to be the header row.
|
|
.PP
|
|
Given a sample.tsv file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name numberOfCats likesApples height
|
|
Gary 1 true 168.8
|
|
Samantha\[aq]s Rabbit 2 false -188.8
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=tsv sample.tsv
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Gary
|
|
numberOfCats: 1
|
|
likesApples: true
|
|
height: 168.8
|
|
- name: Samantha\[aq]s Rabbit
|
|
numberOfCats: 2
|
|
likesApples: false
|
|
height: -188.8
|
|
\f[R]
|
|
.fi
|
|
.SS Round trip
|
|
.PP
|
|
Given a sample.csv file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name,numberOfCats,likesApples,height
|
|
Gary,1,true,168.8
|
|
Samantha\[aq]s Rabbit,2,false,-188.8
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=csv -o=csv \[aq](.[] | select(.name == \[dq]Gary\[dq]) | .numberOfCats) = 3\[aq] sample.csv
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name,numberOfCats,likesApples,height
|
|
Gary,3,true,168.8
|
|
Samantha\[aq]s Rabbit,2,false,-188.8
|
|
\f[R]
|
|
.fi
|
|
.SH Formatting Expressions
|
|
.PP
|
|
\f[C]From version v4.41+\f[R]
|
|
.PP
|
|
You can put expressions into \f[C].yq\f[R] files, use whitespace and
|
|
comments to break up complex expressions and explain what\[cq]s going
|
|
on.
|
|
.SS Using expression files and comments
|
|
.PP
|
|
Note that you can execute the file directly - but make sure you make the
|
|
expression file executable.
|
|
.PP
|
|
Given a sample.yaml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: old
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
And an `update.yq' expression file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
#! yq
|
|
|
|
# This is a yq expression that updates the map
|
|
# for several great reasons outlined here.
|
|
|
|
\&.a.b = \[dq]new\[dq] # line comment here
|
|
| .a.c = \[dq]frog\[dq]
|
|
|
|
# Now good things will happen.
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\&./update.yq sample.yaml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: new
|
|
c: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Flags in expression files
|
|
.PP
|
|
You can specify flags on the shebang line, this only works when
|
|
executing the file directly.
|
|
.PP
|
|
Given a sample.yaml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: old
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
And an `update.yq' expression file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
#! yq -oj
|
|
|
|
# This is a yq expression that updates the map
|
|
# for several great reasons outlined here.
|
|
|
|
\&.a.b = \[dq]new\[dq] # line comment here
|
|
| .a.c = \[dq]frog\[dq]
|
|
|
|
# Now good things will happen.
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
\&./update.yq sample.yaml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
{
|
|
\[dq]a\[dq]: {
|
|
\[dq]b\[dq]: \[dq]new\[dq],
|
|
\[dq]c\[dq]: \[dq]frog\[dq]
|
|
}
|
|
}
|
|
\f[R]
|
|
.fi
|
|
.SS Commenting out yq expressions
|
|
.PP
|
|
Note that \f[C]c\f[R] is no longer set to `frog'.
|
|
In this example we\[cq]re calling yq directly and passing the expression
|
|
file into \f[C]--from-file\f[R], this is no different from executing the
|
|
expression file directly.
|
|
.PP
|
|
Given a sample.yaml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: old
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
And an `update.yq' expression file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
#! yq
|
|
# This is a yq expression that updates the map
|
|
# for several great reasons outlined here.
|
|
|
|
\&.a.b = \[dq]new\[dq] # line comment here
|
|
# | .a.c = \[dq]frog\[dq]
|
|
|
|
# Now good things will happen.
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --from-file update.yq sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: new
|
|
\f[R]
|
|
.fi
|
|
.SS Basic input example
|
|
.PP
|
|
Given a sample.lua file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
return {
|
|
[\[dq]country\[dq]] = \[dq]Australia\[dq]; -- this place
|
|
[\[dq]cities\[dq]] = {
|
|
\[dq]Sydney\[dq],
|
|
\[dq]Melbourne\[dq],
|
|
\[dq]Brisbane\[dq],
|
|
\[dq]Perth\[dq],
|
|
};
|
|
};
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.lua
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
country: Australia
|
|
cities:
|
|
- Sydney
|
|
- Melbourne
|
|
- Brisbane
|
|
- Perth
|
|
\f[R]
|
|
.fi
|
|
.SS Basic output example
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
---
|
|
country: Australia # this place
|
|
cities:
|
|
- Sydney
|
|
- Melbourne
|
|
- Brisbane
|
|
- Perth
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=lua \[aq].\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
return {
|
|
[\[dq]country\[dq]] = \[dq]Australia\[dq]; -- this place
|
|
[\[dq]cities\[dq]] = {
|
|
\[dq]Sydney\[dq],
|
|
\[dq]Melbourne\[dq],
|
|
\[dq]Brisbane\[dq],
|
|
\[dq]Perth\[dq],
|
|
};
|
|
};
|
|
\f[R]
|
|
.fi
|
|
.SS Unquoted keys
|
|
.PP
|
|
Uses the \f[C]--lua-unquoted\f[R] option to produce a nicer-looking
|
|
output.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
---
|
|
country: Australia # this place
|
|
cities:
|
|
- Sydney
|
|
- Melbourne
|
|
- Brisbane
|
|
- Perth
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=lua --lua-unquoted \[aq].\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
return {
|
|
country = \[dq]Australia\[dq]; -- this place
|
|
cities = {
|
|
\[dq]Sydney\[dq],
|
|
\[dq]Melbourne\[dq],
|
|
\[dq]Brisbane\[dq],
|
|
\[dq]Perth\[dq],
|
|
};
|
|
};
|
|
\f[R]
|
|
.fi
|
|
.SS Globals
|
|
.PP
|
|
Uses the \f[C]--lua-globals\f[R] option to export the values into the
|
|
global scope.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
---
|
|
country: Australia # this place
|
|
cities:
|
|
- Sydney
|
|
- Melbourne
|
|
- Brisbane
|
|
- Perth
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=lua --lua-globals \[aq].\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
country = \[dq]Australia\[dq]; -- this place
|
|
cities = {
|
|
\[dq]Sydney\[dq],
|
|
\[dq]Melbourne\[dq],
|
|
\[dq]Brisbane\[dq],
|
|
\[dq]Perth\[dq],
|
|
};
|
|
\f[R]
|
|
.fi
|
|
.SS Elaborate example
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
---
|
|
hello: world
|
|
tables:
|
|
like: this
|
|
keys: values
|
|
? look: non-string keys
|
|
: True
|
|
numbers:
|
|
- decimal: 12345
|
|
- hex: 0x7fabc123
|
|
- octal: 0o30
|
|
- float: 123.45
|
|
- infinity: .inf
|
|
plus_infinity: +.inf
|
|
minus_infinity: -.inf
|
|
- not: .nan
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=lua \[aq].\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
return {
|
|
[\[dq]hello\[dq]] = \[dq]world\[dq];
|
|
[\[dq]tables\[dq]] = {
|
|
[\[dq]like\[dq]] = \[dq]this\[dq];
|
|
[\[dq]keys\[dq]] = \[dq]values\[dq];
|
|
[{
|
|
[\[dq]look\[dq]] = \[dq]non-string keys\[dq];
|
|
}] = true;
|
|
};
|
|
[\[dq]numbers\[dq]] = {
|
|
{
|
|
[\[dq]decimal\[dq]] = 12345;
|
|
},
|
|
{
|
|
[\[dq]hex\[dq]] = 0x7fabc123;
|
|
},
|
|
{
|
|
[\[dq]octal\[dq]] = 24;
|
|
},
|
|
{
|
|
[\[dq]float\[dq]] = 123.45;
|
|
},
|
|
{
|
|
[\[dq]infinity\[dq]] = (1/0);
|
|
[\[dq]plus_infinity\[dq]] = (1/0);
|
|
[\[dq]minus_infinity\[dq]] = (-1/0);
|
|
},
|
|
{
|
|
[\[dq]not\[dq]] = (0/0);
|
|
},
|
|
};
|
|
};
|
|
\f[R]
|
|
.fi
|
|
.SH Properties
|
|
.PP
|
|
Encode/Decode/Roundtrip to/from a property file.
|
|
Line comments on value nodes will be copied across.
|
|
.PP
|
|
By default, empty maps and arrays are not encoded - see below for an
|
|
example on how to encode a value for these.
|
|
.SS Encode properties
|
|
.PP
|
|
Note that empty arrays and maps are not encoded by default.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
person: # neither do comments on maps
|
|
name: Mike Wazowski # comments on values appear
|
|
pets:
|
|
- cat # comments on array values appear
|
|
- nested:
|
|
- list entry
|
|
food: [pizza] # comments on arrays do not
|
|
emptyArray: []
|
|
emptyMap: []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=props sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
# comments on values appear
|
|
person.name = Mike Wazowski
|
|
|
|
# comments on array values appear
|
|
person.pets.0 = cat
|
|
person.pets.1.nested.0 = list entry
|
|
person.food.0 = pizza
|
|
\f[R]
|
|
.fi
|
|
.SS Encode properties with array brackets
|
|
.PP
|
|
Declare the \[en]properties-array-brackets flag to give array paths in
|
|
brackets (e.g.\ SpringBoot).
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
person: # neither do comments on maps
|
|
name: Mike Wazowski # comments on values appear
|
|
pets:
|
|
- cat # comments on array values appear
|
|
- nested:
|
|
- list entry
|
|
food: [pizza] # comments on arrays do not
|
|
emptyArray: []
|
|
emptyMap: []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=props --properties-array-brackets sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
# comments on values appear
|
|
person.name = Mike Wazowski
|
|
|
|
# comments on array values appear
|
|
person.pets[0] = cat
|
|
person.pets[1].nested[0] = list entry
|
|
person.food[0] = pizza
|
|
\f[R]
|
|
.fi
|
|
.SS Encode properties - custom separator
|
|
.PP
|
|
Use the \[en]properties-separator flag to specify your own key/value
|
|
separator.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
person: # neither do comments on maps
|
|
name: Mike Wazowski # comments on values appear
|
|
pets:
|
|
- cat # comments on array values appear
|
|
- nested:
|
|
- list entry
|
|
food: [pizza] # comments on arrays do not
|
|
emptyArray: []
|
|
emptyMap: []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=props --properties-separator=\[dq] :\[at] \[dq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
# comments on values appear
|
|
person.name :\[at] Mike Wazowski
|
|
|
|
# comments on array values appear
|
|
person.pets.0 :\[at] cat
|
|
person.pets.1.nested.0 :\[at] list entry
|
|
person.food.0 :\[at] pizza
|
|
\f[R]
|
|
.fi
|
|
.SS Encode properties: scalar encapsulation
|
|
.PP
|
|
Note that string values with blank characters in them are encapsulated
|
|
with double quotes
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
person: # neither do comments on maps
|
|
name: Mike Wazowski # comments on values appear
|
|
pets:
|
|
- cat # comments on array values appear
|
|
- nested:
|
|
- list entry
|
|
food: [pizza] # comments on arrays do not
|
|
emptyArray: []
|
|
emptyMap: []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=props --unwrapScalar=false sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
# comments on values appear
|
|
person.name = \[dq]Mike Wazowski\[dq]
|
|
|
|
# comments on array values appear
|
|
person.pets.0 = cat
|
|
person.pets.1.nested.0 = \[dq]list entry\[dq]
|
|
person.food.0 = pizza
|
|
\f[R]
|
|
.fi
|
|
.SS Encode properties: no comments
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
person: # neither do comments on maps
|
|
name: Mike Wazowski # comments on values appear
|
|
pets:
|
|
- cat # comments on array values appear
|
|
- nested:
|
|
- list entry
|
|
food: [pizza] # comments on arrays do not
|
|
emptyArray: []
|
|
emptyMap: []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=props \[aq]... comments = \[dq]\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
person.name = Mike Wazowski
|
|
person.pets.0 = cat
|
|
person.pets.1.nested.0 = list entry
|
|
person.food.0 = pizza
|
|
\f[R]
|
|
.fi
|
|
.SS Encode properties: include empty maps and arrays
|
|
.PP
|
|
Use a yq expression to set the empty maps and sequences to your desired
|
|
value.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
person: # neither do comments on maps
|
|
name: Mike Wazowski # comments on values appear
|
|
pets:
|
|
- cat # comments on array values appear
|
|
- nested:
|
|
- list entry
|
|
food: [pizza] # comments on arrays do not
|
|
emptyArray: []
|
|
emptyMap: []
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=props \[aq](.. | select( (tag == \[dq]!!map\[dq] or tag ==\[dq]!!seq\[dq]) and length == 0)) = \[dq]\[dq]\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
# comments on values appear
|
|
person.name = Mike Wazowski
|
|
|
|
# comments on array values appear
|
|
person.pets.0 = cat
|
|
person.pets.1.nested.0 = list entry
|
|
person.food.0 = pizza
|
|
emptyArray =
|
|
emptyMap =
|
|
\f[R]
|
|
.fi
|
|
.SS Decode properties
|
|
.PP
|
|
Given a sample.properties file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
# comments on values appear
|
|
person.name = Mike Wazowski
|
|
|
|
# comments on array values appear
|
|
person.pets.0 = cat
|
|
person.pets.1.nested.0 = list entry
|
|
person.food.0 = pizza
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=props sample.properties
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
person:
|
|
# block comments come through
|
|
# comments on values appear
|
|
name: Mike Wazowski
|
|
pets:
|
|
# comments on array values appear
|
|
- cat
|
|
- nested:
|
|
- list entry
|
|
food:
|
|
- pizza
|
|
\f[R]
|
|
.fi
|
|
.SS Decode properties: numbers
|
|
.PP
|
|
All values are assumed to be strings when parsing properties, but you
|
|
can use the \f[C]from_yaml\f[R] operator on all the strings values to
|
|
autoparse into the correct type.
|
|
.PP
|
|
Given a sample.properties file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a.b = 10
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=props \[aq] (.. | select(tag == \[dq]!!str\[dq])) |= from_yaml\[aq] sample.properties
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
a:
|
|
b: 10
|
|
\f[R]
|
|
.fi
|
|
.SS Decode properties - array should be a map
|
|
.PP
|
|
If you have a numeric map key in your property files, use array_to_map
|
|
to convert them to maps.
|
|
.PP
|
|
Given a sample.properties file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
things.10 = mike
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=props \[aq].things |= array_to_map\[aq] sample.properties
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
things:
|
|
10: mike
|
|
\f[R]
|
|
.fi
|
|
.SS Roundtrip
|
|
.PP
|
|
Given a sample.properties file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
# comments on values appear
|
|
person.name = Mike Wazowski
|
|
|
|
# comments on array values appear
|
|
person.pets.0 = cat
|
|
person.pets.1.nested.0 = list entry
|
|
person.food.0 = pizza
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -p=props -o=props \[aq].person.pets.0 = \[dq]dog\[dq]\[aq] sample.properties
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# block comments come through
|
|
# comments on values appear
|
|
person.name = Mike Wazowski
|
|
|
|
# comments on array values appear
|
|
person.pets.0 = dog
|
|
person.pets.1.nested.0 = list entry
|
|
person.food.0 = pizza
|
|
\f[R]
|
|
.fi
|
|
.SH Recipes
|
|
.PP
|
|
These examples are intended to show how you can use multiple operators
|
|
together so you get an idea of how you can perform complex data
|
|
manipulation.
|
|
.PP
|
|
Please see the details operator
|
|
docs (https://mikefarah.gitbook.io/yq/operators) for details on each
|
|
individual operator.
|
|
.SS Find items in an array
|
|
.PP
|
|
We have an array and we want to find the elements with a particular
|
|
name.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Foo
|
|
numBuckets: 0
|
|
- name: Bar
|
|
numBuckets: 0
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] | select(.name == \[dq]Foo\[dq])\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: Foo
|
|
numBuckets: 0
|
|
\f[R]
|
|
.fi
|
|
.SS Explanation:
|
|
.IP \[bu] 2
|
|
\f[C].[]\f[R] splats the array, and puts all the items in the context.
|
|
.IP \[bu] 2
|
|
These items are then piped (\f[C]|\f[R]) into
|
|
\f[C]select(.name == \[dq]Foo\[dq])\f[R] which will select all the nodes
|
|
that have a name property set to `Foo'.
|
|
.IP \[bu] 2
|
|
See the select (https://mikefarah.gitbook.io/yq/operators/select)
|
|
operator for more information.
|
|
.SS Find and update items in an array
|
|
.PP
|
|
We have an array and we want to \f[I]update\f[R] the elements with a
|
|
particular name.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Foo
|
|
numBuckets: 0
|
|
- name: Bar
|
|
numBuckets: 0
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](.[] | select(.name == \[dq]Foo\[dq]) | .numBuckets) |= . + 1\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- name: Foo
|
|
numBuckets: 1
|
|
- name: Bar
|
|
numBuckets: 0
|
|
\f[R]
|
|
.fi
|
|
.SS Explanation:
|
|
.IP \[bu] 2
|
|
Following from the example above\f[C].[]\f[R] splats the array, selects
|
|
filters the items.
|
|
.IP \[bu] 2
|
|
We then pipe (\f[C]|\f[R]) that into \f[C].numBuckets\f[R], which will
|
|
select that field from all the matching items
|
|
.IP \[bu] 2
|
|
Splat, select and the field are all in brackets, that whole expression
|
|
is passed to the \f[C]|=\f[R] operator as the left hand side expression,
|
|
with \f[C]. + 1\f[R] as the right hand side expression.
|
|
.IP \[bu] 2
|
|
\f[C]|=\f[R] is the operator that updates fields relative to their own
|
|
value, which is referenced as dot (\f[C].\f[R]).
|
|
.IP \[bu] 2
|
|
The expression \f[C]. + 1\f[R] increments the numBuckets counter.
|
|
.IP \[bu] 2
|
|
See the assign (https://mikefarah.gitbook.io/yq/operators/assign-update)
|
|
and add (https://mikefarah.gitbook.io/yq/operators/add) operators for
|
|
more information.
|
|
.SS Deeply prune a tree
|
|
.PP
|
|
Say we are only interested in child1 and child2, and want to filter
|
|
everything else out.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
parentA:
|
|
- bob
|
|
parentB:
|
|
child1: i am child1
|
|
child3: hiya
|
|
parentC:
|
|
childX: cool
|
|
child2: me child2
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq](
|
|
.. | # recurse through all the nodes
|
|
select(has(\[dq]child1\[dq]) or has(\[dq]child2\[dq])) | # match parents that have either child1 or child2
|
|
(.child1, .child2) | # select those children
|
|
select(.) # filter out nulls
|
|
) as $i ireduce({}; # using that set of nodes, create a new result map
|
|
setpath($i | path; $i) # and put in each node, using its original path
|
|
)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
parentB:
|
|
child1: i am child1
|
|
parentC:
|
|
child2: me child2
|
|
\f[R]
|
|
.fi
|
|
.SS Explanation:
|
|
.IP \[bu] 2
|
|
Find all the matching child1 and child2 nodes
|
|
.IP \[bu] 2
|
|
Using ireduce, create a new map using just those nodes
|
|
.IP \[bu] 2
|
|
Set each node into the new map using its original path
|
|
.SS Multiple or complex updates to items in an array
|
|
.PP
|
|
We have an array and we want to \f[I]update\f[R] the elements with a
|
|
particular name in reference to its type.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myArray:
|
|
- name: Foo
|
|
type: cat
|
|
- name: Bar
|
|
type: dog
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq]with(.myArray[]; .name = .name + \[dq] - \[dq] + .type)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myArray:
|
|
- name: Foo - cat
|
|
type: cat
|
|
- name: Bar - dog
|
|
type: dog
|
|
\f[R]
|
|
.fi
|
|
.SS Explanation:
|
|
.IP \[bu] 2
|
|
The with operator will effectively loop through each given item in the
|
|
first given expression, and run the second expression against it.
|
|
.IP \[bu] 2
|
|
\f[C].myArray[]\f[R] splats the array in \f[C]myArray\f[R].
|
|
So \f[C]with\f[R] will run against each item in that array
|
|
.IP \[bu] 2
|
|
\f[C].name = .name + \[dq] - \[dq] + .type\f[R] this expression is run
|
|
against every item, updating the name to be a concatenation of the
|
|
original name as well as the type.
|
|
.IP \[bu] 2
|
|
See the with (https://mikefarah.gitbook.io/yq/operators/with) operator
|
|
for more information and examples.
|
|
.SS Sort an array by a field
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myArray:
|
|
- name: Foo
|
|
numBuckets: 1
|
|
- name: Bar
|
|
numBuckets: 0
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].myArray |= sort_by(.numBuckets)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
myArray:
|
|
- name: Bar
|
|
numBuckets: 0
|
|
- name: Foo
|
|
numBuckets: 1
|
|
\f[R]
|
|
.fi
|
|
.SS Explanation:
|
|
.IP \[bu] 2
|
|
We want to resort \f[C].myArray\f[R].
|
|
.IP \[bu] 2
|
|
\f[C]sort_by\f[R] works by piping an array into it, and it pipes out a
|
|
sorted array.
|
|
.IP \[bu] 2
|
|
So, we use \f[C]|=\f[R] to update \f[C].myArray\f[R].
|
|
This is the same as doing
|
|
\f[C].myArray = (.myArray | sort_by(.numBuckets))\f[R]
|
|
.SS Filter, flatten, sort and unique
|
|
.PP
|
|
Lets find the unique set of names from the document.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- type: foo
|
|
names:
|
|
- Fred
|
|
- Catherine
|
|
- type: bar
|
|
names:
|
|
- Zelda
|
|
- type: foo
|
|
names: Fred
|
|
- type: foo
|
|
names: Ava
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq][.[] | select(.type == \[dq]foo\[dq]) | .names] | flatten | sort | unique\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- Ava
|
|
- Catherine
|
|
- Fred
|
|
\f[R]
|
|
.fi
|
|
.SS Explanation:
|
|
.IP \[bu] 2
|
|
\f[C].[] | select(.type == \[dq]foo\[dq]) | .names\f[R] will select the
|
|
array elements of type \[lq]foo\[rq]
|
|
.IP \[bu] 2
|
|
Splat \f[C].[]\f[R] will unwrap the array and match all the items.
|
|
We need to do this so we can work on the child items, for instance,
|
|
filter items out using the \f[C]select\f[R] operator.
|
|
.IP \[bu] 2
|
|
But we still want the final results back into an array.
|
|
So after we\[cq]re doing working on the children, we wrap everything
|
|
back into an array using square brackets around the expression.
|
|
\f[C][.[] | select(.type == \[dq]foo\[dq]) | .names]\f[R]
|
|
.IP \[bu] 2
|
|
Now have have an array of all the `names' values.
|
|
Which includes arrays of strings as well as strings on their own.
|
|
.IP \[bu] 2
|
|
Pipe \f[C]|\f[R] this array through \f[C]flatten\f[R].
|
|
This will flatten nested arrays.
|
|
So now we have a flat list of all the name value strings
|
|
.IP \[bu] 2
|
|
Next we pipe \f[C]|\f[R] that through \f[C]sort\f[R] and then
|
|
\f[C]unique\f[R] to get a sorted, unique list of the names!
|
|
.IP \[bu] 2
|
|
See the flatten (https://mikefarah.gitbook.io/yq/operators/flatten),
|
|
sort (https://mikefarah.gitbook.io/yq/operators/sort) and
|
|
unique (https://mikefarah.gitbook.io/yq/operators/unique) for more
|
|
information and examples.
|
|
.SS Export as environment variables (script), or any custom format
|
|
.PP
|
|
Given a yaml document, lets output a script that will configure
|
|
environment variables with that data.
|
|
This same approach can be used for exporting into custom formats.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
var0: string0
|
|
var1: string1
|
|
fruit:
|
|
- apple
|
|
- banana
|
|
- peach
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].[] |(
|
|
( select(kind == \[dq]scalar\[dq]) | key + \[dq]=\[aq]\[rs]\[aq]\[aq]\[dq] + . + \[dq]\[aq]\[rs]\[aq]\[aq]\[dq]),
|
|
( select(kind == \[dq]seq\[dq]) | key + \[dq]=(\[dq] + (map(\[dq]\[aq]\[rs]\[aq]\[aq]\[dq] + . + \[dq]\[aq]\[rs]\[aq]\[aq]\[dq]) | join(\[dq],\[dq])) + \[dq])\[dq])
|
|
)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
var0=\[aq]string0\[aq]
|
|
var1=\[aq]string1\[aq]
|
|
fruit=(\[aq]apple\[aq],\[aq]banana\[aq],\[aq]peach\[aq])
|
|
\f[R]
|
|
.fi
|
|
.SS Explanation:
|
|
.IP \[bu] 2
|
|
\f[C].[]\f[R] matches all top level elements
|
|
.IP \[bu] 2
|
|
We need a string expression for each of the different types that will
|
|
produce the bash syntax, we\[cq]ll use the union operator, to join them
|
|
together
|
|
.IP \[bu] 2
|
|
Scalars, we just need the key and quoted value:
|
|
\f[C]( select(kind == \[dq]scalar\[dq]) | key + \[dq]=\[aq]\[dq] + . + \[dq]\[aq]\[dq])\f[R]
|
|
.IP \[bu] 2
|
|
Sequences (or arrays) are trickier, we need to quote each value and
|
|
\f[C]join\f[R] them with \f[C],\f[R]:
|
|
\f[C]map(\[dq]\[aq]\[dq] + . + \[dq]\[aq]\[dq]) | join(\[dq],\[dq])\f[R]
|
|
.SS Custom format with nested data
|
|
.PP
|
|
Like the previous example, but lets handle nested data structures.
|
|
In this custom example, we\[cq]re going to join the property paths with
|
|
_.
|
|
The important thing to keep in mind is that our expression is not
|
|
recursive (despite the data structure being so).
|
|
Instead we match \f[I]all\f[R] elements on the tree and operate on them.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
simple: string0
|
|
simpleArray:
|
|
- apple
|
|
- banana
|
|
- peach
|
|
deep:
|
|
property: value
|
|
array:
|
|
- cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].. |(
|
|
( select(kind == \[dq]scalar\[dq] and parent | kind != \[dq]seq\[dq]) | (path | join(\[dq]_\[dq])) + \[dq]=\[aq]\[rs]\[aq]\[aq]\[dq] + . + \[dq]\[aq]\[rs]\[aq]\[aq]\[dq]),
|
|
( select(kind == \[dq]seq\[dq]) | (path | join(\[dq]_\[dq])) + \[dq]=(\[dq] + (map(\[dq]\[aq]\[rs]\[aq]\[aq]\[dq] + . + \[dq]\[aq]\[rs]\[aq]\[aq]\[dq]) | join(\[dq],\[dq])) + \[dq])\[dq])
|
|
)\[aq] sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
simple=\[aq]string0\[aq]
|
|
deep_property=\[aq]value\[aq]
|
|
simpleArray=(\[aq]apple\[aq],\[aq]banana\[aq],\[aq]peach\[aq])
|
|
deep_array=(\[aq]cat\[aq])
|
|
\f[R]
|
|
.fi
|
|
.SS Explanation:
|
|
.IP \[bu] 2
|
|
You\[cq]ll need to understand how the previous example works to
|
|
understand this extension.
|
|
.IP \[bu] 2
|
|
\f[C]..\f[R] matches \f[I]all\f[R] elements, instead of \f[C].[]\f[R]
|
|
from the previous example that just matches top level elements.
|
|
.IP \[bu] 2
|
|
Like before, we need a string expression for each of the different types
|
|
that will produce the bash syntax, we\[cq]ll use the union operator, to
|
|
join them together
|
|
.IP \[bu] 2
|
|
This time, however, our expression matches every node in the data
|
|
structure.
|
|
.IP \[bu] 2
|
|
We only want to print scalars that are not in arrays (because we handle
|
|
the separately), so well add
|
|
\f[C]and parent | kind != \[dq]seq\[dq]\f[R] to the select operator
|
|
expression for scalars
|
|
.IP \[bu] 2
|
|
We don\[cq]t just want the key any more, we want the full path.
|
|
So instead of \f[C]key\f[R] we have \f[C]path | join(\[dq]_\[dq])\f[R]
|
|
.IP \[bu] 2
|
|
The expression for sequences follows the same logic
|
|
.SS Encode shell variables
|
|
.PP
|
|
Note that comments are dropped and values will be enclosed in single
|
|
quotes as needed.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# comment
|
|
name: Mike Wazowski
|
|
eyes:
|
|
color: turquoise
|
|
number: 1
|
|
friends:
|
|
- James P. Sullivan
|
|
- Celia Mae
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=shell sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name=\[aq]Mike Wazowski\[aq]
|
|
eyes_color=turquoise
|
|
eyes_number=1
|
|
friends_0=\[aq]James P. Sullivan\[aq]
|
|
friends_1=\[aq]Celia Mae\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Encode shell variables: illegal variable names as key.
|
|
.PP
|
|
Keys that would be illegal as variable keys are adapted.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
ascii_=_symbols: replaced with _
|
|
\[dq]ascii_ _controls\[dq]: dropped (this example uses \[rs]t)
|
|
nonascii_\[u05D0]_characters: dropped
|
|
effort_expe\[~n]ded_t\[`o]_preserve_accented_latin_letters: moderate (via unicode NFKD)
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=shell sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
ascii___symbols=\[aq]replaced with _\[aq]
|
|
ascii__controls=\[aq]dropped (this example uses \[rs]t)\[aq]
|
|
nonascii__characters=dropped
|
|
effort_expended_to_preserve_accented_latin_letters=\[aq]moderate (via unicode NFKD)\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SS Encode shell variables: empty values, arrays and maps
|
|
.PP
|
|
Empty values are encoded to empty variables, but empty arrays and maps
|
|
are skipped.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
empty:
|
|
value:
|
|
array: []
|
|
map: {}
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=shell sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
empty_value=
|
|
\f[R]
|
|
.fi
|
|
.SS Encode shell variables: single quotes in values
|
|
.PP
|
|
Single quotes in values are encoded as `\[lq]'\[lq]\[cq] (close single
|
|
quote, double-quoted single quote, open single quote).
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name: Miles O\[aq]Brien
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=shell sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name=\[aq]Miles O\[aq]\[dq]\[aq]\[dq]\[aq]Brien\[aq]
|
|
\f[R]
|
|
.fi
|
|
.SH TOML
|
|
.PP
|
|
Decode from TOML.
|
|
Note that \f[C]yq\f[R] does not yet support outputting in TOML format
|
|
(and therefore it cannot roundtrip)
|
|
.SS Parse: Simple
|
|
.PP
|
|
Given a sample.toml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
A = \[dq]hello\[dq]
|
|
B = 12
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.toml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
A: hello
|
|
B: 12
|
|
\f[R]
|
|
.fi
|
|
.SS Parse: Deep paths
|
|
.PP
|
|
Given a sample.toml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
person.name = \[dq]hello\[dq]
|
|
person.address = \[dq]12 cat st\[dq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.toml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
person:
|
|
name: hello
|
|
address: 12 cat st
|
|
\f[R]
|
|
.fi
|
|
.SS Encode: Scalar
|
|
.PP
|
|
Given a sample.toml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
person.name = \[dq]hello\[dq]
|
|
person.address = \[dq]12 cat st\[dq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].person.name\[aq] sample.toml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
hello
|
|
\f[R]
|
|
.fi
|
|
.SS Parse: inline table
|
|
.PP
|
|
Given a sample.toml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name = { first = \[dq]Tom\[dq], last = \[dq]Preston-Werner\[dq] }
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.toml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
name:
|
|
first: Tom
|
|
last: Preston-Werner
|
|
\f[R]
|
|
.fi
|
|
.SS Parse: Array Table
|
|
.PP
|
|
Given a sample.toml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[owner.contact]
|
|
name = \[dq]Tom Preston-Werner\[dq]
|
|
age = 36
|
|
|
|
[[owner.addresses]]
|
|
street = \[dq]first street\[dq]
|
|
suburb = \[dq]ok\[dq]
|
|
|
|
[[owner.addresses]]
|
|
street = \[dq]second street\[dq]
|
|
suburb = \[dq]nice\[dq]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.toml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
owner:
|
|
contact:
|
|
name: Tom Preston-Werner
|
|
age: 36
|
|
addresses:
|
|
- street: first street
|
|
suburb: ok
|
|
- street: second street
|
|
suburb: nice
|
|
\f[R]
|
|
.fi
|
|
.SS Parse: Empty Table
|
|
.PP
|
|
Given a sample.toml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
[dependencies]
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.toml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
dependencies: {}
|
|
\f[R]
|
|
.fi
|
|
.SH XML
|
|
.PP
|
|
Encode and decode to and from XML.
|
|
Whitespace is not conserved for round trips - but the order of the
|
|
fields are.
|
|
.PP
|
|
Consecutive xml nodes with the same name are assumed to be arrays.
|
|
.PP
|
|
XML content data, attributes processing instructions and directives are
|
|
all created as plain fields.
|
|
.PP
|
|
This can be controlled by:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
l l l.
|
|
T{
|
|
Flag
|
|
T}@T{
|
|
Default
|
|
T}@T{
|
|
Sample XML
|
|
T}
|
|
_
|
|
T{
|
|
\f[C]--xml-attribute-prefix\f[R]
|
|
T}@T{
|
|
\f[C]+\f[R] (changing to \f[C]+\[at]\f[R] soon)
|
|
T}@T{
|
|
Legs in \f[C]<cat legs=\[dq]4\[dq]/>\f[R]
|
|
T}
|
|
T{
|
|
\f[C]--xml-content-name\f[R]
|
|
T}@T{
|
|
\f[C]+content\f[R]
|
|
T}@T{
|
|
Meow in \f[C]<cat>Meow <fur>true</true></cat>\f[R]
|
|
T}
|
|
T{
|
|
\f[C]--xml-directive-name\f[R]
|
|
T}@T{
|
|
\f[C]+directive\f[R]
|
|
T}@T{
|
|
\f[C]<!DOCTYPE config system \[dq]blah\[dq]>\f[R]
|
|
T}
|
|
T{
|
|
\f[C]--xml-proc-inst-prefix\f[R]
|
|
T}@T{
|
|
\f[C]+p_\f[R]
|
|
T}@T{
|
|
\f[C]<?xml version=\[dq]1\[dq]?>\f[R]
|
|
T}
|
|
.TE
|
|
.PP
|
|
{% hint style=\[lq]warning\[rq] %} Default Attribute Prefix will be
|
|
changing in v4.30! In order to avoid name conflicts (e.g.\ having an
|
|
attribute named \[lq]content\[rq] will create a field that clashes with
|
|
the default content name of \[lq]+content\[rq]) the attribute prefix
|
|
will be changing to \[lq]+\[at]\[rq].
|
|
.PP
|
|
This will affect users that have not set their own prefix and are not
|
|
roundtripping XML changes.
|
|
.PP
|
|
{% endhint %}
|
|
.SS Encoder / Decoder flag options
|
|
.PP
|
|
In addition to the above flags, there are the following xml
|
|
encoder/decoder options controlled by flags:
|
|
.PP
|
|
.TS
|
|
tab(@);
|
|
lw(23.3n) lw(23.3n) lw(23.3n).
|
|
T{
|
|
Flag
|
|
T}@T{
|
|
Default
|
|
T}@T{
|
|
Description
|
|
T}
|
|
_
|
|
T{
|
|
\f[C]--xml-strict-mode\f[R]
|
|
T}@T{
|
|
false
|
|
T}@T{
|
|
Strict mode enforces the requirements of the XML specification.
|
|
When switched off the parser allows input containing common mistakes.
|
|
See the Golang xml decoder (https://pkg.go.dev/encoding/xml#Decoder) for
|
|
more details.
|
|
T}
|
|
T{
|
|
\f[C]--xml-keep-namespace\f[R]
|
|
T}@T{
|
|
true
|
|
T}@T{
|
|
Keeps the namespace of attributes
|
|
T}
|
|
T{
|
|
\f[C]--xml-raw-token\f[R]
|
|
T}@T{
|
|
true
|
|
T}@T{
|
|
Does not verify that start and end elements match and does not translate
|
|
name space prefixes to their corresponding URLs.
|
|
T}
|
|
T{
|
|
\f[C]--xml-skip-proc-inst\f[R]
|
|
T}@T{
|
|
false
|
|
T}@T{
|
|
Skips over processing instructions,
|
|
e.g.\ \f[C]<?xml version=\[dq]1\[dq]?>\f[R]
|
|
T}
|
|
T{
|
|
\f[C]--xml-skip-directives\f[R]
|
|
T}@T{
|
|
false
|
|
T}@T{
|
|
Skips over directives,
|
|
e.g.\ \f[C]<!DOCTYPE config system \[dq]blah\[dq]>\f[R]
|
|
T}
|
|
.TE
|
|
.PP
|
|
See below for examples
|
|
.SS Parse xml: simple
|
|
.PP
|
|
Notice how all the values are strings, see the next example on how you
|
|
can fix that.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]?>
|
|
<cat>
|
|
<says>meow</says>
|
|
<legs>4</legs>
|
|
<cute>true</cute>
|
|
</cat>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
+p_xml: version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]
|
|
cat:
|
|
says: meow
|
|
legs: \[dq]4\[dq]
|
|
cute: \[dq]true\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: number
|
|
.PP
|
|
All values are assumed to be strings when parsing XML, but you can use
|
|
the \f[C]from_yaml\f[R] operator on all the strings values to autoparse
|
|
into the correct type.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]?>
|
|
<cat>
|
|
<says>meow</says>
|
|
<legs>4</legs>
|
|
<cute>true</cute>
|
|
</cat>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq] (.. | select(tag == \[dq]!!str\[dq])) |= from_yaml\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
+p_xml: version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]
|
|
cat:
|
|
says: meow
|
|
legs: 4
|
|
cute: true
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: array
|
|
.PP
|
|
Consecutive nodes with identical xml names are assumed to be arrays.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]?>
|
|
<animal>cat</animal>
|
|
<animal>goat</animal>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
+p_xml: version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]
|
|
animal:
|
|
- cat
|
|
- goat
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: force as an array
|
|
.PP
|
|
In XML, if your array has a single item, then yq doesn\[cq]t know its an
|
|
array.
|
|
This is how you can consistently force it to be an array.
|
|
This handles the 3 scenarios of having nothing in the array, having a
|
|
single item and having multiple.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<zoo><animal>cat</animal></zoo>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].zoo.animal |= ([] + .)\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
zoo:
|
|
animal:
|
|
- cat
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: force all as an array
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<zoo><thing><frog>boing</frog></thing></zoo>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].. |= [] + .\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
- zoo:
|
|
- thing:
|
|
- frog:
|
|
- boing
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: attributes
|
|
.PP
|
|
Attributes are converted to fields, with the default attribute prefix
|
|
`+'.
|
|
Use \[cq]\[en]xml-attribute-prefix\[ga] to set your own.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]?>
|
|
<cat legs=\[dq]4\[dq]>
|
|
<legs>7</legs>
|
|
</cat>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
+p_xml: version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]
|
|
cat:
|
|
+\[at]legs: \[dq]4\[dq]
|
|
legs: \[dq]7\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: attributes with content
|
|
.PP
|
|
Content is added as a field, using the default content name of
|
|
\f[C]+content\f[R].
|
|
Use \f[C]--xml-content-name\f[R] to set your own.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]?>
|
|
<cat legs=\[dq]4\[dq]>meow</cat>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
+p_xml: version=\[dq]1.0\[dq] encoding=\[dq]UTF-8\[dq]
|
|
cat:
|
|
+content: meow
|
|
+\[at]legs: \[dq]4\[dq]
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: content split between comments/children
|
|
.PP
|
|
Multiple content texts are collected into a sequence.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<root> value <!-- comment-->anotherValue <a>frog</a> cool!</root>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
root:
|
|
+content: # comment
|
|
- value
|
|
- anotherValue
|
|
- cool!
|
|
a: frog
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: custom dtd
|
|
.PP
|
|
DTD entities are processed as directives.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<!DOCTYPE root [
|
|
<!ENTITY writer \[dq]Blah.\[dq]>
|
|
<!ENTITY copyright \[dq]Blah\[dq]>
|
|
]>
|
|
<root>
|
|
<item>&writer;©right;</item>
|
|
</root>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<!DOCTYPE root [
|
|
<!ENTITY writer \[dq]Blah.\[dq]>
|
|
<!ENTITY copyright \[dq]Blah\[dq]>
|
|
]>
|
|
<root>
|
|
<item>&writer;&copyright;</item>
|
|
</root>
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: skip custom dtd
|
|
.PP
|
|
DTDs are directives, skip over directives to skip DTDs.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<!DOCTYPE root [
|
|
<!ENTITY writer \[dq]Blah.\[dq]>
|
|
<!ENTITY copyright \[dq]Blah\[dq]>
|
|
]>
|
|
<root>
|
|
<item>&writer;©right;</item>
|
|
</root>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --xml-skip-directives \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<root>
|
|
<item>&writer;&copyright;</item>
|
|
</root>
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: with comments
|
|
.PP
|
|
A best attempt is made to preserve comments.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<!-- before cat -->
|
|
<cat>
|
|
<!-- in cat before -->
|
|
<x>3<!-- multi
|
|
line comment
|
|
for x --></x>
|
|
<!-- before y -->
|
|
<y>
|
|
<!-- in y before -->
|
|
<d><!-- in d before -->z<!-- in d after --></d>
|
|
|
|
<!-- in y after -->
|
|
</y>
|
|
<!-- in_cat_after -->
|
|
</cat>
|
|
<!-- after cat -->
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -oy \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
# before cat
|
|
cat:
|
|
# in cat before
|
|
x: \[dq]3\[dq] # multi
|
|
# line comment
|
|
# for x
|
|
# before y
|
|
|
|
y:
|
|
# in y before
|
|
# in d before
|
|
d: z # in d after
|
|
# in y after
|
|
# in_cat_after
|
|
# after cat
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: keep attribute namespace
|
|
.PP
|
|
Defaults to true
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<map xmlns=\[dq]some-namespace\[dq] xmlns:xsi=\[dq]some-instance\[dq] xsi:schemaLocation=\[dq]some-url\[dq]></map>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --xml-keep-namespace=false \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<map xmlns=\[dq]some-namespace\[dq] xsi=\[dq]some-instance\[dq] schemaLocation=\[dq]some-url\[dq]></map>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
instead of
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<map xmlns=\[dq]some-namespace\[dq] xmlns:xsi=\[dq]some-instance\[dq] xsi:schemaLocation=\[dq]some-url\[dq]></map>
|
|
\f[R]
|
|
.fi
|
|
.SS Parse xml: keep raw attribute namespace
|
|
.PP
|
|
Defaults to true
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<map xmlns=\[dq]some-namespace\[dq] xmlns:xsi=\[dq]some-instance\[dq] xsi:schemaLocation=\[dq]some-url\[dq]></map>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq --xml-raw-token=false \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<map xmlns=\[dq]some-namespace\[dq] xmlns:xsi=\[dq]some-instance\[dq] some-instance:schemaLocation=\[dq]some-url\[dq]></map>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
instead of
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<map xmlns=\[dq]some-namespace\[dq] xmlns:xsi=\[dq]some-instance\[dq] xsi:schemaLocation=\[dq]some-url\[dq]></map>
|
|
\f[R]
|
|
.fi
|
|
.SS Encode xml: simple
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat: purrs
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=xml sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<cat>purrs</cat>
|
|
\f[R]
|
|
.fi
|
|
.SS Encode xml: array
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
pets:
|
|
cat:
|
|
- purrs
|
|
- meows
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=xml sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<pets>
|
|
<cat>purrs</cat>
|
|
<cat>meows</cat>
|
|
</pets>
|
|
\f[R]
|
|
.fi
|
|
.SS Encode xml: attributes
|
|
.PP
|
|
Fields with the matching xml-attribute-prefix are assumed to be
|
|
attributes.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat:
|
|
+\[at]name: tiger
|
|
meows: true
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=xml sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<cat name=\[dq]tiger\[dq]>
|
|
<meows>true</meows>
|
|
</cat>
|
|
\f[R]
|
|
.fi
|
|
.SS Encode xml: attributes with content
|
|
.PP
|
|
Fields with the matching xml-content-name is assumed to be content.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
cat:
|
|
+\[at]name: tiger
|
|
+content: cool
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=xml sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<cat name=\[dq]tiger\[dq]>cool</cat>
|
|
\f[R]
|
|
.fi
|
|
.SS Encode xml: comments
|
|
.PP
|
|
A best attempt is made to copy comments to xml.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
#
|
|
# header comment
|
|
# above_cat
|
|
#
|
|
cat: # inline_cat
|
|
# above_array
|
|
array: # inline_array
|
|
- val1 # inline_val1
|
|
# above_val2
|
|
- val2 # inline_val2
|
|
# below_cat
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=xml sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<!--
|
|
header comment
|
|
above_cat
|
|
-->
|
|
<!-- inline_cat -->
|
|
<cat><!-- above_array inline_array -->
|
|
<array>val1<!-- inline_val1 --></array>
|
|
<array><!-- above_val2 -->val2<!-- inline_val2 --></array>
|
|
</cat><!-- below_cat -->
|
|
\f[R]
|
|
.fi
|
|
.SS Encode: doctype and xml declaration
|
|
.PP
|
|
Use the special xml names to add/modify proc instructions and
|
|
directives.
|
|
.PP
|
|
Given a sample.yml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
+p_xml: version=\[dq]1.0\[dq]
|
|
+directive: \[aq]DOCTYPE config SYSTEM \[dq]/etc/iwatch/iwatch.dtd\[dq] \[aq]
|
|
apple:
|
|
+p_coolioo: version=\[dq]1.0\[dq]
|
|
+directive: \[aq]CATYPE meow purr puss \[aq]
|
|
b: things
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq -o=xml sample.yml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<!DOCTYPE config SYSTEM \[dq]/etc/iwatch/iwatch.dtd\[dq] >
|
|
<apple><?coolioo version=\[dq]1.0\[dq]?><!CATYPE meow purr puss >
|
|
<b>things</b>
|
|
</apple>
|
|
\f[R]
|
|
.fi
|
|
.SS Round trip: with comments
|
|
.PP
|
|
A best effort is made, but comment positions and white space are not
|
|
preserved perfectly.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<!-- before cat -->
|
|
<cat>
|
|
<!-- in cat before -->
|
|
<x>3<!-- multi
|
|
line comment
|
|
for x --></x>
|
|
<!-- before y -->
|
|
<y>
|
|
<!-- in y before -->
|
|
<d><!-- in d before -->z<!-- in d after --></d>
|
|
|
|
<!-- in y after -->
|
|
</y>
|
|
<!-- in_cat_after -->
|
|
</cat>
|
|
<!-- after cat -->
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<!-- before cat -->
|
|
<cat><!-- in cat before -->
|
|
<x>3<!-- multi
|
|
line comment
|
|
for x --></x><!-- before y -->
|
|
<y><!-- in y before
|
|
in d before -->
|
|
<d>z<!-- in d after --></d><!-- in y after -->
|
|
</y><!-- in_cat_after -->
|
|
</cat><!-- after cat -->
|
|
\f[R]
|
|
.fi
|
|
.SS Roundtrip: with doctype and declaration
|
|
.PP
|
|
yq parses XML proc instructions and directives into nodes.
|
|
Unfortunately the underlying XML parser loses whitespace information.
|
|
.PP
|
|
Given a sample.xml file of:
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<!DOCTYPE config SYSTEM \[dq]/etc/iwatch/iwatch.dtd\[dq] >
|
|
<apple>
|
|
<?coolioo version=\[dq]1.0\[dq]?>
|
|
<!CATYPE meow purr puss >
|
|
<b>things</b>
|
|
</apple>
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
then
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
yq \[aq].\[aq] sample.xml
|
|
\f[R]
|
|
.fi
|
|
.PP
|
|
will output
|
|
.IP
|
|
.nf
|
|
\f[C]
|
|
<?xml version=\[dq]1.0\[dq]?>
|
|
<!DOCTYPE config SYSTEM \[dq]/etc/iwatch/iwatch.dtd\[dq] >
|
|
<apple><?coolioo version=\[dq]1.0\[dq]?><!CATYPE meow purr puss >
|
|
<b>things</b>
|
|
</apple>
|
|
\f[R]
|
|
.fi
|
|
.SH AUTHORS
|
|
Mike Farah.
|