mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-07 14:25:38 +00:00
Compare commits
9 Commits
af2ecf48bf
...
5368f4f730
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5368f4f730 | ||
|
|
383cd0f182 | ||
|
|
3727b3e664 | ||
|
|
c477fc08cf | ||
|
|
1846006082 | ||
|
|
dff0122481 | ||
|
|
42b92aff13 | ||
|
|
c76e432de3 | ||
|
|
19e2591b1e |
@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.22.5 as builder
|
FROM golang:1.23.0 as builder
|
||||||
|
|
||||||
WORKDIR /go/src/mikefarah/yq
|
WORKDIR /go/src/mikefarah/yq
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.22.5
|
FROM golang:1.23.0
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y npm && \
|
apt-get install -y npm && \
|
||||||
|
|||||||
2
Makefile
2
Makefile
@ -2,7 +2,7 @@ MAKEFLAGS += --warn-undefined-variables
|
|||||||
SHELL := /bin/bash
|
SHELL := /bin/bash
|
||||||
.SHELLFLAGS := -o pipefail -euc
|
.SHELLFLAGS := -o pipefail -euc
|
||||||
.DEFAULT_GOAL := install
|
.DEFAULT_GOAL := install
|
||||||
ENGINE := $(shell { command -v podman || command -v docker; } 2>/dev/null)
|
ENGINE := $(shell { (podman version > /dev/null 2>&1 && command -v podman) || command -v docker; } 2>/dev/null)
|
||||||
|
|
||||||
include Makefile.variables
|
include Makefile.variables
|
||||||
|
|
||||||
|
|||||||
@ -241,6 +241,14 @@ As these are supported by the community :heart: - however, they may be out of da
|
|||||||
_Please note that the Debian package (previously supported by @rmescandon) is no longer maintained. Please use an alternative installation method._
|
_Please note that the Debian package (previously supported by @rmescandon) is no longer maintained. Please use an alternative installation method._
|
||||||
|
|
||||||
|
|
||||||
|
### X-CMD
|
||||||
|
Checkout `yq` on x-cmd: https://x-cmd.com/mod/yq
|
||||||
|
|
||||||
|
- Instant Results: See the output of your yq filter in real-time.
|
||||||
|
- Error Handling: Encounter a syntax error? It will display the error message and the results of the closest valid filter
|
||||||
|
|
||||||
|
Thanks @edwinjhlee!
|
||||||
|
|
||||||
### Nix
|
### Nix
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
6
go.mod
6
go.mod
@ -16,8 +16,8 @@ require (
|
|||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/yuin/gopher-lua v1.1.1
|
github.com/yuin/gopher-lua v1.1.1
|
||||||
golang.org/x/net v0.27.0
|
golang.org/x/net v0.28.0
|
||||||
golang.org/x/text v0.16.0
|
golang.org/x/text v0.17.0
|
||||||
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
|
gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
@ -26,7 +26,7 @@ require (
|
|||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
golang.org/x/sys v0.22.0 // indirect
|
golang.org/x/sys v0.23.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
16
go.sum
16
go.sum
@ -60,16 +60,16 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
|
|||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
|
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
|
||||||
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
|
||||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
|
||||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
|
||||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
|||||||
@ -8,20 +8,20 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type base64Padder struct {
|
type base64Padder struct {
|
||||||
count uint64
|
count int
|
||||||
io.Reader
|
io.Reader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *base64Padder) pad(buf []byte) (int, error) {
|
func (c *base64Padder) pad(buf []byte) (int, error) {
|
||||||
pad := strings.Repeat("=", int(4-c.count%4))
|
pad := strings.Repeat("=", (4 - c.count%4))
|
||||||
n, err := strings.NewReader(pad).Read(buf)
|
n, err := strings.NewReader(pad).Read(buf)
|
||||||
c.count += uint64(n)
|
c.count += n
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *base64Padder) Read(buf []byte) (int, error) {
|
func (c *base64Padder) Read(buf []byte) (int, error) {
|
||||||
n, err := c.Reader.Read(buf)
|
n, err := c.Reader.Read(buf)
|
||||||
c.count += uint64(n)
|
c.count += n
|
||||||
|
|
||||||
if err == io.EOF && c.count%4 != 0 {
|
if err == io.EOF && c.count%4 != 0 {
|
||||||
return c.pad(buf)
|
return c.pad(buf)
|
||||||
|
|||||||
@ -1,3 +1,10 @@
|
|||||||
|
# Kind
|
||||||
|
|
||||||
|
The `kind` operator identifies the type of a node as either `scalar`, `map`, or `seq`.
|
||||||
|
|
||||||
|
This can be used for filtering or transforming nodes based on their type.
|
||||||
|
|
||||||
|
Note that `null` values are treated as `scalar`.
|
||||||
|
|
||||||
## Get kind
|
## Get kind
|
||||||
Given a sample.yml file of:
|
Given a sample.yml file of:
|
||||||
|
|||||||
@ -37,6 +37,25 @@ fruit: banana
|
|||||||
name: sam
|
name: sam
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Get parent attribute
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
a:
|
||||||
|
fruit: apple
|
||||||
|
name: bob
|
||||||
|
b:
|
||||||
|
fruit: banana
|
||||||
|
name: sam
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq '.. | select(. == "banana") | parent.name' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
sam
|
||||||
|
```
|
||||||
|
|
||||||
## N-th parent
|
## N-th parent
|
||||||
You can optionally supply the number of levels to go up for the parent, the default being 1.
|
You can optionally supply the number of levels to go up for the parent, the default being 1.
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,30 @@ myMap:
|
|||||||
cat: meow
|
cat: meow
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Pick keys from map, included all the keys
|
||||||
|
We create a map of the picked keys plus all the current keys, and run that through unique
|
||||||
|
|
||||||
|
Given a sample.yml file of:
|
||||||
|
```yaml
|
||||||
|
myMap:
|
||||||
|
cat: meow
|
||||||
|
dog: bark
|
||||||
|
thing: hamster
|
||||||
|
hamster: squeak
|
||||||
|
```
|
||||||
|
then
|
||||||
|
```bash
|
||||||
|
yq '.myMap |= pick( (["thing"] + keys) | unique)' sample.yml
|
||||||
|
```
|
||||||
|
will output
|
||||||
|
```yaml
|
||||||
|
myMap:
|
||||||
|
thing: hamster
|
||||||
|
cat: meow
|
||||||
|
dog: bark
|
||||||
|
hamster: squeak
|
||||||
|
```
|
||||||
|
|
||||||
## Pick indices from array
|
## Pick indices from array
|
||||||
Note that the order of the indices matches the pick order and non existent indices are skipped.
|
Note that the order of the indices matches the pick order and non existent indices are skipped.
|
||||||
|
|
||||||
|
|||||||
@ -517,7 +517,7 @@ func parentWithLevel() yqAction {
|
|||||||
|
|
||||||
prefs := parentOpPreferences{Level: level}
|
prefs := parentOpPreferences{Level: level}
|
||||||
op := &Operation{OperationType: getParentOpType, Value: getParentOpType.Type, StringValue: value, Preferences: prefs}
|
op := &Operation{OperationType: getParentOpType, Value: getParentOpType.Type, StringValue: value, Preferences: prefs}
|
||||||
return &token{TokenType: operationToken, Operation: op}, nil
|
return &token{TokenType: operationToken, Operation: op, CheckForPostTraverse: true}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,7 +525,7 @@ func parentWithDefaultLevel() yqAction {
|
|||||||
return func(rawToken lexer.Token) (*token, error) {
|
return func(rawToken lexer.Token) (*token, error) {
|
||||||
prefs := parentOpPreferences{Level: 1}
|
prefs := parentOpPreferences{Level: 1}
|
||||||
op := &Operation{OperationType: getParentOpType, Value: getParentOpType.Type, StringValue: getParentOpType.Type, Preferences: prefs}
|
op := &Operation{OperationType: getParentOpType, Value: getParentOpType.Type, StringValue: getParentOpType.Type, Preferences: prefs}
|
||||||
return &token{TokenType: operationToken, Operation: op}, nil
|
return &token{TokenType: operationToken, Operation: op, CheckForPostTraverse: true}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,14 @@ var parentOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[b], (!!map)::{fruit: banana, name: sam}\n",
|
"D0, P[b], (!!map)::{fruit: banana, name: sam}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "Get parent attribute",
|
||||||
|
document: `{a: {fruit: apple, name: bob}, b: {fruit: banana, name: sam}}`,
|
||||||
|
expression: `.. | select(. == "banana") | parent.name`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[b name], (!!str)::sam\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "N-th parent",
|
description: "N-th parent",
|
||||||
subdescription: "You can optionally supply the number of levels to go up for the parent, the default being 1.",
|
subdescription: "You can optionally supply the number of levels to go up for the parent, the default being 1.",
|
||||||
|
|||||||
@ -14,6 +14,15 @@ var pickOperatorScenarios = []expressionScenario{
|
|||||||
"D0, P[], (!!map)::myMap: {hamster: squeak, cat: meow}\n",
|
"D0, P[], (!!map)::myMap: {hamster: squeak, cat: meow}\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "Pick keys from map, included all the keys",
|
||||||
|
subdescription: "We create a map of the picked keys plus all the current keys, and run that through unique",
|
||||||
|
document: "myMap: {cat: meow, dog: bark, thing: hamster, hamster: squeak}\n",
|
||||||
|
expression: `.myMap |= pick( (["thing"] + keys) | unique)`,
|
||||||
|
expected: []string{
|
||||||
|
"D0, P[], (!!map)::myMap: {thing: hamster, cat: meow, dog: bark, hamster: squeak}\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "Pick splat",
|
description: "Pick splat",
|
||||||
skipDoc: true,
|
skipDoc: true,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user