Simplified yq usage

This commit is contained in:
Mike Farah 2022-01-28 12:50:13 +11:00
parent 9896245f71
commit 2e3f5e410e
10 changed files with 48 additions and 46 deletions

View File

@ -8,22 +8,22 @@ yq is written in go - so you can download a dependency free binary for your plat
Read a value: Read a value:
```bash ```bash
yq e '.a.b[0].c' file.yaml yq '.a.b[0].c' file.yaml
``` ```
Pipe from STDIN: Pipe from STDIN:
```bash ```bash
cat file.yaml | yq e '.a.b[0].c' - cat file.yaml | yq '.a.b[0].c'
``` ```
Update a yaml file, inplace Update a yaml file, inplace
```bash ```bash
yq e -i '.a.b[0].c = "cool"' file.yaml yq -i '.a.b[0].c = "cool"' file.yaml
``` ```
Update using environment variables Update using environment variables
```bash ```bash
NAME=mike yq e -i '.a.b[0].c = strenv(NAME)' file.yaml NAME=mike yq -i '.a.b[0].c = strenv(NAME)' file.yaml
``` ```
Merge multiple files Merge multiple files
@ -33,7 +33,7 @@ yq ea '. as $item ireduce ({}; . * $item )' path/to/*.yml
Multiple updates to a yaml file Multiple updates to a yaml file
```bash ```bash
yq e -i ' yq -i '
.a.b[0].c = "cool" | .a.b[0].c = "cool" |
.x.y.z = "foobar" | .x.y.z = "foobar" |
.person.name = strenv(NAME) .person.name = strenv(NAME)

View File

@ -6,6 +6,8 @@ description: >-
# Evaluate # Evaluate
Note that (as of 4.18.1) this is the default command when none is supplied to yq.
## Usage:  ## Usage: 
```bash ```bash
@ -20,20 +22,20 @@ Note that you can pass in `-` as a filename to pipe from STDIN.
```bash ```bash
# runs the expression against each file, in series # runs the expression against each file, in series
yq e '.a.b | length' f1.yml f2.yml yq '.a.b | length' f1.yml f2.yml
# '-' will pipe from STDIN # '-' will pipe from STDIN
cat file.yml | yq e '.a.b' f1.yml - f2.yml cat file.yml | yq '.a.b' f1.yml - f2.yml
# prints out the file # prints out the file
yq e sample.yaml yq sample.yaml
cat sample.yml | yq e cat sample.yml | yq e
# prints a new yaml document # prints a new yaml document
yq e -n '.a.b.c = "cat"' yq -n '.a.b.c = "cat"'
# updates file.yaml directly # updates file.yaml directly
yq e '.a.b = "cool"' -i file.yaml yq '.a.b = "cool"' -i file.yaml
``` ```

View File

@ -27,7 +27,7 @@ yq r sample.yaml 'a.b.c'
v4: v4:
``` ```
yq e '.a.b.c' sample.yaml yq '.a.b.c' sample.yaml
``` ```
### Reading with default value ### Reading with default value
@ -41,7 +41,7 @@ yq r sample.yaml --defaultValue frog path.not.there
v4: (use the [alternative](broken-reference) operator) v4: (use the [alternative](broken-reference) operator)
``` ```
yq e '.path.not.there // "frog"' sample.yaml yq '.path.not.there // "frog"' sample.yaml
``` ```
@ -57,7 +57,7 @@ yq r sample.yaml 'a.(b.d==cat).f'
v4: v4:
```bash ```bash
yq eval '.a | select(.b.d == "cat") | .f' sample.yaml yq '.a | select(.b.d == "cat") | .f' sample.yaml
``` ```
### Recursively match nodes ### Recursively match nodes
@ -71,7 +71,7 @@ yq r sample.yaml 'thing.**.name'
v4: v4:
``` ```
yq e '.thing | .. | select(has("name"))' sample.yaml yq '.thing | .. | select(has("name"))' sample.yaml
``` ```
### Multiple documents ### Multiple documents
@ -85,7 +85,7 @@ yq r -d1 sample.yaml 'b.c'
v4 (via the document index operator): v4 (via the document index operator):
```bash ```bash
yq eval 'select(documentIndex == 1) | .b.c' sample.yml yq 'select(documentIndex == 1) | .b.c' sample.yml
``` ```
### Updating / writing documents ### Updating / writing documents
@ -99,7 +99,7 @@ yq w sample.yaml 'a.b.c' fred
v4: v4:
``` ```
yq eval '.a.b.c = "fred"' sample.yaml yq '.a.b.c = "fred"' sample.yaml
``` ```
### Deleting documents ### Deleting documents
@ -113,7 +113,7 @@ yq d sample.yaml 'a.b.c'
v4: v4:
```bash ```bash
yq eval 'del(.a.b.c)' sample.yaml yq 'del(.a.b.c)' sample.yaml
``` ```
### Merging documents ### Merging documents
@ -137,7 +137,7 @@ yq p data1.yaml c.d
v4: v4:
``` ```
yq eval '{"c": {"d": . }}' data1.yml yq '{"c": {"d": . }}' data1.yml
``` ```
### Create new yaml documents ### Create new yaml documents
@ -153,7 +153,7 @@ yq n b.c cat
v4: v4:
``` ```
yq e -n '.b.c = "cat"' yq -n '.b.c = "cat"'
``` ```
### Validate documents ### Validate documents
@ -167,13 +167,13 @@ yq validate some.file
v4: v4:
``` ```
yq e 'true' some.file > /dev/null yq 'true' some.file > /dev/null
``` ```
Note that passing 'true' as the expression saves having to reencode the yaml (only to pipe it to stdout). In v4 you can also do a slightly more sophisticated validation and assert the tag on the root level, so you can ensure the yaml file is a map or array at the top level: Note that passing 'true' as the expression saves having to reencode the yaml (only to pipe it to stdout). In v4 you can also do a slightly more sophisticated validation and assert the tag on the root level, so you can ensure the yaml file is a map or array at the top level:
``` ```
yq e --exit-status 'tag == "!!map" or tag== "!!seq"' some.file > /dev/null yq --exit-status 'tag == "!!map" or tag== "!!seq"' some.file > /dev/null
``` ```
### Comparing yaml files ### Comparing yaml files
@ -189,7 +189,7 @@ v4:
In v4 there is no built in compare command, instead it relies on using diff. The downside is longer syntax, the upside is that you can use the full power of diff. In v4 there is no built in compare command, instead it relies on using diff. The downside is longer syntax, the upside is that you can use the full power of diff.
``` ```
diff <(yq e -P file1.yml) <(yq e -P file2.yml) diff <(yq -P file1.yml) <(yq -P file2.yml)
``` ```
### Script files ### Script files
@ -209,7 +209,7 @@ V4 doesn't have a similar feature, however the fact that you can run multiple op
```bash ```bash
#!/bin/bash #!/bin/bash
yq e ' yq '
.a.key1 = "things" | .a.key1 = "things" |
del(.a.ab.key2) del(.a.ab.key2)
' ./examples/data1.yaml ' ./examples/data1.yaml

View File

@ -16,7 +16,7 @@ Compatible structures is either an array of scalars (strings/numbers/booleans),
then then
```bash ```bash
yq e '.' -o=csv sample.yaml yq '.' -o=csv sample.yaml
``` ```
will output: will output:
@ -29,7 +29,7 @@ because,excel,is,cool
Similarly, for tsv: Similarly, for tsv:
```bash ```bash
yq e '.' -o=tsv sample.yaml yq '.' -o=tsv sample.yaml
``` ```
will output: will output:

View File

@ -19,7 +19,7 @@ b: bannana
The running The running
``` ```
yq e --front-matter=process '.a="chocolate"' file.jekyll yq --front-matter=process '.a="chocolate"' file.jekyll
``` ```
Will yield: Will yield:
@ -37,7 +37,7 @@ b: bannana
Running with `--front-matter=extract` will only output the yaml contents and ignore the rest. From the previous example, if you were to instead run: Running with `--front-matter=extract` will only output the yaml contents and ignore the rest. From the previous example, if you were to instead run:
``` ```
yq e --front-matter=extract '.a="chocolate"' file.jekyll yq --front-matter=extract '.a="chocolate"' file.jekyll
``` ```
Then this would yield: Then this would yield:

View File

@ -8,7 +8,7 @@ You can use `yq` in your GitHub action, for instance:
id: lookupSdkVersion id: lookupSdkVersion
uses: mikefarah/yq@master uses: mikefarah/yq@master
with: with:
cmd: yq eval '.renutil.version' 'config.yml' cmd: yq '.renutil.version' 'config.yml'
- name: Restore Cache - name: Restore Cache
id: restore-cache id: restore-cache
uses: actions/cache@v2 uses: actions/cache@v2

View File

@ -37,7 +37,7 @@ apples:
Then: Then:
``` ```
yq e -I4 sample.yaml yq -I4 sample.yaml
``` ```
Will print out: Will print out:
@ -53,7 +53,7 @@ apples:
This also works with json This also works with json
``` ```
yq e -j -I4 sample.yaml yq -j -I4 sample.yaml
``` ```
yields yields
@ -86,7 +86,7 @@ a: "Things" # cool stuff
Then: Then:
`yq e --unwrapScalar=false '.a' data.yml` `yq --unwrapScalar=false '.a' data.yml`
Will yield: Will yield:

View File

@ -18,7 +18,7 @@ person: # neither do comments on maps
then then
```bash ```bash
yq eval -o=p sample.yaml yq -o=p sample.yaml
``` ```
will output: will output:

View File

@ -15,7 +15,7 @@ a: test_doc2
Then running: Then running:
```bash ```bash
yq e -s '.a' myfile.yml yq -s '.a' myfile.yml
``` ```
will result in two files: will result in two files:
@ -40,7 +40,7 @@ TIP: if you don't want the leading document separators (`---`), then run with th
This is like the example above, but we'll use `$index` for the filename. Note that this variable is only defined for the `--split-exp/s` flag. This is like the example above, but we'll use `$index` for the filename. Note that this variable is only defined for the `--split-exp/s` flag.
``` ```
yq e -s '"file_" + $index' myfile.yml yq -s '"file_" + $index' myfile.yml
``` ```
This will create two files, `file_0.yml` and `file_1.yml`. This will create two files, `file_0.yml` and `file_1.yml`.
@ -59,7 +59,7 @@ You can also split results into separate files. Notice
Then, by splatting the array into individual results, we can split the content into several files: Then, by splatting the array into individual results, we can split the content into several files:
```bash ```bash
yq e '.[]' file.yml -s '"user_" + .name' yq '.[]' file.yml -s '"user_" + .name'
``` ```
will result in two files: will result in two files:

View File

@ -5,7 +5,7 @@
Yaml files can be surprisingly lenient in what can be parsed as a yaml file. A reasonable way of validation a yaml file is to ensure the top level is a map or array (although it is valid yaml to have scalars at the top level, but often this is not what you want). This can be done by: Yaml files can be surprisingly lenient in what can be parsed as a yaml file. A reasonable way of validation a yaml file is to ensure the top level is a map or array (although it is valid yaml to have scalars at the top level, but often this is not what you want). This can be done by:
``` ```
yq e --exit-status 'tag == "!!map" or tag== "!!seq"' file.txt > /dev/null yq --exit-status 'tag == "!!map" or tag== "!!seq"' file.txt > /dev/null
``` ```
## Split expressions over multiple lines to improve readability ## Split expressions over multiple lines to improve readability
@ -15,7 +15,7 @@ Feel free to use multiple lines in your expression to improve readability.
Use `with` if you need to make several updates to the same path. Use `with` if you need to make several updates to the same path.
```bash ```bash
yq eval --inplace ' yq --inplace '
with(.a.deeply.nested; with(.a.deeply.nested;
. = "newValue" | . style="single") | . = "newValue" | . style="single") |
with(.b.another.nested; with(.b.another.nested;
@ -37,7 +37,7 @@ coolActions:
You can create a bash array named `actions` by: You can create a bash array named `actions` by:
```bash ```bash
> readarray actions < <(yq e '.coolActions[]' sample.yaml) > readarray actions < <(yq '.coolActions[]' sample.yaml)
> echo "${actions[1]}" > echo "${actions[1]}"
edit edit
``` ```
@ -47,7 +47,7 @@ edit
Use an environment variable with the `strenv` operator to inject the contents from an environment variable. Use an environment variable with the `strenv` operator to inject the contents from an environment variable.
```bash ```bash
LICENSE=$(cat LICENSE) yq eval -n '.a = strenv(LICENSE)' LICENSE=$(cat LICENSE) yq -n '.a = strenv(LICENSE)'
``` ```
Note that `bash` substitution "$(..)" trims newlines, this will cause string blocks to start with `|-` instead of `|`. If you want to keep your nice trailing newline, read more [here](https://mikefarah.gitbook.io/yq/operators/string-operators#string-blocks-bash-and-newlines) Note that `bash` substitution "$(..)" trims newlines, this will cause string blocks to start with `|-` instead of `|`. If you want to keep your nice trailing newline, read more [here](https://mikefarah.gitbook.io/yq/operators/string-operators#string-blocks-bash-and-newlines)
@ -58,7 +58,7 @@ Note that `bash` substitution "$(..)" trims newlines, this will cause string blo
The `strenv` operator is a great way to handle special characters in strings: The `strenv` operator is a great way to handle special characters in strings:
```bash ```bash
VAL='.a |!@ == "string2"' yq e '.a = strenv(VAL)' example.yaml VAL='.a |!@ == "string2"' yq '.a = strenv(VAL)' example.yaml
``` ```
## Quotes in Windows Powershell ## Quotes in Windows Powershell
@ -66,7 +66,7 @@ VAL='.a |!@ == "string2"' yq e '.a = strenv(VAL)' example.yaml
Powershell has its [own](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about\_quoting\_rules?view=powershell-7.1) way of handling quotes: Powershell has its [own](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about\_quoting\_rules?view=powershell-7.1) way of handling quotes:
```bash ```bash
PS > yq e -n '.test = ""something""' PS > yq -n '.test = ""something""'
test: something test: something
PS > PS >
``` ```
@ -90,7 +90,7 @@ See [here](https://mikefarah.gitbook.io/yq/operators/multiply-merge#merge-arrays
To create a new `yaml` file simply: To create a new `yaml` file simply:
``` ```
yq e -n '.someNew="content"' > newfile.yml yq -n '.someNew="content"' > newfile.yml
``` ```
## Comparing yaml files ## Comparing yaml files
@ -98,7 +98,7 @@ yq e -n '.someNew="content"' > newfile.yml
The best way to run a diff is to use `yq` to normalise the yaml files and then just use diff. Here is a simple example of using pretty print `-P` to normalise the styling and running diff: The best way to run a diff is to use `yq` to normalise the yaml files and then just use diff. Here is a simple example of using pretty print `-P` to normalise the styling and running diff:
``` ```
diff <(yq e -P 'sort_keys(..)' file1.yaml) <(yq e -P 'sort_keys(..)' file2.yaml) diff <(yq -P 'sort_keys(..)' file1.yaml) <(yq -P 'sort_keys(..)' file2.yaml)
``` ```
This way you can use the full power of `diff` and normalise the yaml files as you like. This way you can use the full power of `diff` and normalise the yaml files as you like.
@ -110,7 +110,7 @@ You may also want to remove all comments using `... comments=""`
Like `diff` and other bash commands, you can use `<(exp)` to pipe in multiple streams of data into `yq`. instance: Like `diff` and other bash commands, you can use `<(exp)` to pipe in multiple streams of data into `yq`. instance:
``` ```
yq e '.apple' <(curl -s https://somewhere/data1.yaml) <(cat file.yml) yq '.apple' <(curl -s https://somewhere/data1.yaml) <(cat file.yml)
``` ```
## Updating deeply selected paths ## Updating deeply selected paths
@ -127,7 +127,7 @@ yq '(.foo.bar[] | select(name == "fred) | .apple) = "cool"'
In order to combine multiple yaml files into a single file (with `---` separators) you can just: In order to combine multiple yaml files into a single file (with `---` separators) you can just:
``` ```
yq e '.' somewhere/*.yaml yq '.' somewhere/*.yaml
``` ```
## Multiple updates to the same path ## Multiple updates to the same path
@ -135,7 +135,7 @@ yq e '.' somewhere/*.yaml
You can use the [with](../operators/with.md) operator to set a nested context: You can use the [with](../operators/with.md) operator to set a nested context:
``` ```
yq eval 'with(.a.deeply ; .nested = "newValue" | .other= "newThing")' sample.yml yq 'with(.a.deeply ; .nested = "newValue" | .other= "newThing")' sample.yml
``` ```
The first argument expression sets the root context, and the second expression runs against that root context. The first argument expression sets the root context, and the second expression runs against that root context.