This commit is contained in:
Mike Farah 2020-12-27 09:36:33 +11:00
parent 6a13c8b78f
commit f7f8bed955
31 changed files with 409 additions and 374 deletions

View File

@ -8,11 +8,8 @@ Use `+=` as append assign for things like increment. `.a += .x` is equivalent to
## Concatenate and assign arrays ## Concatenate and assign arrays
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {val: thing, b: [cat, dog]}
val: thing '': null
b:
- cat
- dog
``` ```
then then
```bash ```bash
@ -20,23 +17,16 @@ yq eval '.a.b += ["cow"]' sample.yml
``` ```
will output will output
```yaml ```yaml
a: a: {val: thing, b: [cat, dog, cow]}
val: thing '': null
b:
- cat
- dog
- cow
``` ```
## Concatenate arrays ## Concatenate arrays
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [1, 2]
- 1 b: [3, 4]
- 2 '': null
b:
- 3
- 4
``` ```
then then
```bash ```bash
@ -44,18 +34,14 @@ yq eval '.a + .b' sample.yml
``` ```
will output will output
```yaml ```yaml
- 1 [1, 2, 3, 4]
- 2
- 3
- 4
``` ```
## Concatenate null to array ## Concatenate null to array
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [1, 2]
- 1 '': null
- 2
``` ```
then then
```bash ```bash
@ -63,18 +49,15 @@ yq eval '.a + null' sample.yml
``` ```
will output will output
```yaml ```yaml
- 1 [1, 2]
- 2
``` ```
## Add object to array ## Add object to array
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [1, 2]
- 1 c: {cat: meow}
- 2 '': null
c:
cat: meow
``` ```
then then
```bash ```bash
@ -82,17 +65,14 @@ yq eval '.a + .c' sample.yml
``` ```
will output will output
```yaml ```yaml
- 1 [1, 2, {cat: meow}]
- 2
- cat: meow
``` ```
## Add string to array ## Add string to array
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [1, 2]
- 1 '': null
- 2
``` ```
then then
```bash ```bash
@ -100,20 +80,15 @@ yq eval '.a + "hello"' sample.yml
``` ```
will output will output
```yaml ```yaml
- 1 [1, 2, hello]
- 2
- hello
``` ```
## Update array (append) ## Update array (append)
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [1, 2]
- 1 b: [3, 4]
- 2 '': null
b:
- 3
- 4
``` ```
then then
```bash ```bash
@ -121,13 +96,8 @@ yq eval '.a = .a + .b' sample.yml
``` ```
will output will output
```yaml ```yaml
a: a: [1, 2, 3, 4]
- 1 b: [3, 4]
- 2 '': null
- 3
- 4
b:
- 3
- 4
``` ```

View File

@ -4,6 +4,7 @@ This operator is used to provide alternative (or default) values when a particul
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: bridge a: bridge
'': null
``` ```
then then
```bash ```bash
@ -32,6 +33,7 @@ hello
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: ~ a: ~
'': null
``` ```
then then
```bash ```bash
@ -46,6 +48,7 @@ hello
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: false a: false
'': null
``` ```
then then
```bash ```bash
@ -61,6 +64,7 @@ Given a sample.yml file of:
```yaml ```yaml
a: false a: false
b: cat b: cat
'': null
``` ```
then then
```bash ```bash

View File

@ -7,6 +7,7 @@ Use the `alias` and `anchor` operators to read and write yaml aliases and anchor
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: &billyBob cat a: &billyBob cat
'': null
``` ```
then then
```bash ```bash
@ -21,6 +22,7 @@ billyBob
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
``` ```
then then
```bash ```bash
@ -29,6 +31,7 @@ yq eval '.a anchor = "foobar"' sample.yml
will output will output
```yaml ```yaml
a: &foobar cat a: &foobar cat
'': null
``` ```
## Get alias ## Get alias
@ -36,6 +39,7 @@ Given a sample.yml file of:
```yaml ```yaml
b: &billyBob meow b: &billyBob meow
a: *billyBob a: *billyBob
'': null
``` ```
then then
```bash ```bash
@ -51,6 +55,7 @@ Given a sample.yml file of:
```yaml ```yaml
b: &meow purr b: &meow purr
a: cat a: cat
'': null
``` ```
then then
```bash ```bash
@ -60,14 +65,14 @@ will output
```yaml ```yaml
b: &meow purr b: &meow purr
a: *meow a: *meow
'': null
``` ```
## Explode alias and anchor ## Explode alias and anchor
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
f: f: {a: &a cat, b: *a}
a: &a cat '': null
b: *a
``` ```
then then
```bash ```bash
@ -75,15 +80,15 @@ yq eval 'explode(.f)' sample.yml
``` ```
will output will output
```yaml ```yaml
f: f: {a: cat, b: cat}
a: cat '': null
b: cat
``` ```
## Explode with no aliases or anchors ## Explode with no aliases or anchors
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: mike a: mike
'': null
``` ```
then then
```bash ```bash
@ -92,14 +97,14 @@ yq eval 'explode(.a)' sample.yml
will output will output
```yaml ```yaml
a: mike a: mike
'': null
``` ```
## Explode with alias keys ## Explode with alias keys
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
f: f: {a: &a cat, *a: b}
a: &a cat '': null
*a: b
``` ```
then then
```bash ```bash
@ -107,9 +112,8 @@ yq eval 'explode(.f)' sample.yml
``` ```
will output will output
```yaml ```yaml
f: f: {a: cat, cat: b}
a: cat '': null
cat: b
``` ```
## Explode with merge anchors ## Explode with merge anchors
@ -125,14 +129,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -157,5 +160,6 @@ foobar:
c: foo_c c: foo_c
a: foo_a a: foo_a
thing: foobar_thing thing: foobar_thing
'': null
``` ```

View File

@ -20,9 +20,8 @@ x: frog
## Update node to be the child value ## Update node to be the child value
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: {g: foof}}
b: '': null
g: foof
``` ```
then then
```bash ```bash
@ -30,16 +29,16 @@ yq eval '.a |= .b' sample.yml
``` ```
will output will output
```yaml ```yaml
a: a: {g: foof}
g: foof '': null
``` ```
## Update node to be the sibling value ## Update node to be the sibling value
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: child}
b: child
b: sibling b: sibling
'': null
``` ```
then then
```bash ```bash
@ -49,6 +48,7 @@ will output
```yaml ```yaml
a: sibling a: sibling
b: sibling b: sibling
'': null
``` ```
## Updated multiple paths ## Updated multiple paths
@ -57,6 +57,7 @@ Given a sample.yml file of:
a: fieldA a: fieldA
b: fieldB b: fieldB
c: fieldC c: fieldC
'': null
``` ```
then then
```bash ```bash
@ -67,13 +68,14 @@ will output
a: potatoe a: potatoe
b: fieldB b: fieldB
c: potatoe c: potatoe
'': null
``` ```
## Update string value ## Update string value
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: apple}
b: apple '': null
``` ```
then then
```bash ```bash
@ -81,8 +83,8 @@ yq eval '.a.b = "frog"' sample.yml
``` ```
will output will output
```yaml ```yaml
a: a: {b: frog}
b: frog '': null
``` ```
## Update string value via |= ## Update string value via |=
@ -90,8 +92,8 @@ Note there is no difference between `=` and `|=` when the RHS is a scalar
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: apple}
b: apple '': null
``` ```
then then
```bash ```bash
@ -99,26 +101,24 @@ yq eval '.a.b |= "frog"' sample.yml
``` ```
will output will output
```yaml ```yaml
a: a: {b: frog}
b: frog '': null
``` ```
## Update selected results ## Update selected results
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: apple, c: cactus}
b: apple '': null
c: cactus
``` ```
then then
```bash ```bash
yq eval '(.a.[] | select(. == "apple")) = "frog"' sample.yml yq eval '(.a[] | select(. == "apple")) = "frog"' sample.yml
``` ```
will output will output
```yaml ```yaml
a: a: {b: frog, c: cactus}
b: frog '': null
c: cactus
``` ```
## Update array values ## Update array values

View File

@ -24,10 +24,13 @@ Given a sample.yml file of:
```yaml ```yaml
- a: bird - a: bird
b: dog b: dog
'': null
- a: frog - a: frog
b: bird b: bird
'': null
- a: cat - a: cat
b: fly b: fly
'': null
``` ```
then then
```bash ```bash
@ -37,8 +40,10 @@ will output
```yaml ```yaml
- a: bird - a: bird
b: dog b: dog
'': null
- a: cat - a: cat
b: fly b: fly
'': null
``` ```
## Not true is false ## Not true is false

View File

@ -28,6 +28,7 @@ Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
b: dog b: dog
'': null
``` ```
then then
```bash ```bash

View File

@ -13,6 +13,7 @@ will output
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
name: Mike name: Mike
'': null
``` ```
then then
```bash ```bash
@ -22,15 +23,15 @@ will output
```yaml ```yaml
wrap: wrap:
name: Mike name: Mike
'': null
``` ```
## Using splat to create multiple objects ## Using splat to create multiple objects
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
name: Mike name: Mike
pets: pets: [cat, dog]
- cat '': null
- dog
``` ```
then then
```bash ```bash
@ -46,14 +47,12 @@ Mike: dog
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
name: Mike name: Mike
pets: pets: [cat, dog]
- cat '': null
- dog
--- ---
name: Rosey name: Rosey
pets: pets: [monkey, sheep]
- monkey '': null
- sheep
``` ```
then then
```bash ```bash

View File

@ -3,6 +3,7 @@ Use these comment operators to set or retrieve comments.
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
``` ```
then then
```bash ```bash
@ -11,12 +12,14 @@ yq eval '.a lineComment="single"' sample.yml
will output will output
```yaml ```yaml
a: cat # single a: cat # single
'': null
``` ```
## Set head comment ## Set head comment
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
``` ```
then then
```bash ```bash
@ -27,12 +30,14 @@ will output
# single # single
a: cat a: cat
'': null
``` ```
## Set foot comment, using an expression ## Set foot comment, using an expression
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
``` ```
then then
```bash ```bash
@ -41,6 +46,7 @@ yq eval '. footComment=.a' sample.yml
will output will output
```yaml ```yaml
a: cat a: cat
'': null
# cat # cat
``` ```
@ -50,6 +56,7 @@ Given a sample.yml file of:
```yaml ```yaml
a: cat # comment a: cat # comment
b: dog # leave this b: dog # leave this
'': null
``` ```
then then
```bash ```bash
@ -59,12 +66,14 @@ will output
```yaml ```yaml
a: cat a: cat
b: dog # leave this b: dog # leave this
'': null
``` ```
## Remove all comments ## Remove all comments
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat # comment a: cat # comment
'': null
``` ```
then then
```bash ```bash
@ -72,13 +81,15 @@ yq eval '.. comments=""' sample.yml
``` ```
will output will output
```yaml ```yaml
a: cat a: cat # comment
'': null
``` ```
## Get line comment ## Get line comment
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat # meow a: cat # meow
'': null
``` ```
then then
```bash ```bash
@ -93,6 +104,7 @@ meow
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat # meow a: cat # meow
'': null
``` ```
then then
```bash ```bash
@ -107,6 +119,7 @@ will output
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat # meow a: cat # meow
'': null
``` ```
then then
```bash ```bash

View File

@ -4,6 +4,7 @@ Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
b: dog b: dog
'': null
``` ```
then then
```bash ```bash
@ -12,14 +13,14 @@ yq eval 'del(.b)' sample.yml
will output will output
```yaml ```yaml
a: cat a: cat
'': null
``` ```
## Delete nested entry in map ## Delete nested entry in map
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {a1: fred, a2: frood}
a1: fred '': null
a2: frood
``` ```
then then
```bash ```bash
@ -27,8 +28,8 @@ yq eval 'del(.a.a1)' sample.yml
``` ```
will output will output
```yaml ```yaml
a: a: {a2: frood}
a2: frood '': null
``` ```
## Delete entry in array ## Delete entry in array
@ -53,6 +54,7 @@ Given a sample.yml file of:
```yaml ```yaml
- a: cat - a: cat
b: dog b: dog
'': null
``` ```
then then
```bash ```bash
@ -61,6 +63,7 @@ yq eval 'del(.[0].a)' sample.yml
will output will output
```yaml ```yaml
- b: dog - b: dog
'': null
``` ```
## Delete no matches ## Delete no matches
@ -68,6 +71,7 @@ Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
b: dog b: dog
'': null
``` ```
then then
```bash ```bash
@ -77,6 +81,7 @@ will output
```yaml ```yaml
a: cat a: cat
b: dog b: dog
'': null
``` ```
## Delete matching entries ## Delete matching entries
@ -85,6 +90,7 @@ Given a sample.yml file of:
a: cat a: cat
b: dog b: dog
c: bat c: bat
'': null
``` ```
then then
```bash ```bash
@ -93,5 +99,6 @@ yq eval 'del( .[] | select(. == "*at") )' sample.yml
will output will output
```yaml ```yaml
b: dog b: dog
'': null
``` ```

View File

@ -3,8 +3,10 @@ Use the `documentIndex` operator to select nodes of a particular document.
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
--- ---
a: frog a: frog
'': null
``` ```
then then
```bash ```bash
@ -21,8 +23,10 @@ will output
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
--- ---
a: frog a: frog
'': null
``` ```
then then
```bash ```bash
@ -31,14 +35,17 @@ yq eval 'select(. | documentIndex == 1)' sample.yml
will output will output
```yaml ```yaml
a: frog a: frog
'': null
``` ```
## Print Document Index with matches ## Print Document Index with matches
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
--- ---
a: frog a: frog
'': null
``` ```
then then
```bash ```bash
@ -46,9 +53,7 @@ yq eval '.a | ({"match": ., "doc": (. | documentIndex)})' sample.yml
``` ```
will output will output
```yaml ```yaml
match: cat '': null
doc: 0 '': null
match: frog
doc: 1
``` ```

View File

@ -9,6 +9,7 @@ yq eval-all 'select(fileIndex == 0) * select(filename == "file2.yaml")' file1.ya
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
``` ```
then then
```bash ```bash
@ -23,6 +24,7 @@ sample.yaml
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
``` ```
then then
```bash ```bash

View File

@ -2,10 +2,14 @@ This is operation that returns true if the key exists in a map (or index in an a
## Has map key ## Has map key
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
- a: yes - a: "yes"
'': null
- a: ~ - a: ~
'': null
- a: - a:
'': null
- b: nope - b: nope
'': null
``` ```
then then
```bash ```bash

View File

@ -6,6 +6,7 @@ returns length of string
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
'': null
``` ```
then then
```bash ```bash
@ -23,6 +24,7 @@ Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
c: dog c: dog
'': null
``` ```
then then
```bash ```bash
@ -30,7 +32,7 @@ yq eval 'length' sample.yml
``` ```
will output will output
```yaml ```yaml
2 3
``` ```
## Array length ## Array length

View File

@ -16,13 +16,9 @@ yq eval-all 'select(fileIndex == 0) * select(fileIndex == 1)' file1.yaml file2.y
## Merge objects together, returning merged result only ## Merge objects together, returning merged result only
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {field: me, fieldA: cat}
field: me b: {field: {g: wizz}, fieldB: dog}
fieldA: cat '': null
b:
field:
g: wizz
fieldB: dog
``` ```
then then
```bash ```bash
@ -30,22 +26,15 @@ yq eval '.a * .b' sample.yml
``` ```
will output will output
```yaml ```yaml
field: {'': null}
g: wizz
fieldA: cat
fieldB: dog
``` ```
## Merge objects together, returning parent object ## Merge objects together, returning parent object
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {field: me, fieldA: cat}
field: me b: {field: {g: wizz}, fieldB: dog}
fieldA: cat '': null
b:
field:
g: wizz
fieldB: dog
``` ```
then then
```bash ```bash
@ -53,15 +42,7 @@ yq eval '. * {"a":.b}' sample.yml
``` ```
will output will output
```yaml ```yaml
a: '': null
field:
g: wizz
fieldA: cat
fieldB: dog
b:
field:
g: wizz
fieldB: dog
``` ```
## Merge keeps style of LHS ## Merge keeps style of LHS
@ -78,22 +59,15 @@ yq eval '. * {"a":.b}' sample.yml
``` ```
will output will output
```yaml ```yaml
a: {things: great, also: "me"} '': null
b:
also: "me"
``` ```
## Merge arrays ## Merge arrays
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [1, 2, 3]
- 1 b: [3, 4, 5]
- 2 '': null
- 3
b:
- 3
- 4
- 5
``` ```
then then
```bash ```bash
@ -101,31 +75,15 @@ yq eval '. * {"a":.b}' sample.yml
``` ```
will output will output
```yaml ```yaml
a: '': null
- 3
- 4
- 5
b:
- 3
- 4
- 5
``` ```
## Merge, appending arrays ## Merge, appending arrays
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {array: [1, 2, {animal: dog}], value: coconut}
array: b: {array: [3, 4, {animal: cat}], value: banana}
- 1 '': null
- 2
- animal: dog
value: coconut
b:
array:
- 3
- 4
- animal: cat
value: banana
``` ```
then then
```bash ```bash
@ -133,14 +91,7 @@ yq eval '.a *+ .b' sample.yml
``` ```
will output will output
```yaml ```yaml
array: {'': null}
- 1
- 2
- animal: dog
- 3
- 4
- animal: cat
value: banana
``` ```
## Merge to prefix an element ## Merge to prefix an element
@ -148,6 +99,7 @@ Given a sample.yml file of:
```yaml ```yaml
a: cat a: cat
b: dog b: dog
'': null
``` ```
then then
```bash ```bash
@ -155,20 +107,16 @@ yq eval '. * {"a": {"c": .a}}' sample.yml
``` ```
will output will output
```yaml ```yaml
a: '': null
c: cat
b: dog
``` ```
## Merge with simple aliases ## Merge with simple aliases
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: &cat a: &cat {c: frog}
c: frog b: {f: *cat}
b: c: {g: thongs}
f: *cat '': null
c:
g: thongs
``` ```
then then
```bash ```bash
@ -176,19 +124,16 @@ yq eval '.c * .b' sample.yml
``` ```
will output will output
```yaml ```yaml
g: thongs {'': null}
f: *cat
``` ```
## Merge does not copy anchor names ## Merge does not copy anchor names
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {c: &cat frog}
c: &cat frog b: {f: *cat}
b: c: {g: thongs}
f: *cat '': null
c:
g: thongs
``` ```
then then
```bash ```bash
@ -196,8 +141,7 @@ yq eval '.c * .a' sample.yml
``` ```
will output will output
```yaml ```yaml
g: thongs {'': null}
c: frog
``` ```
## Merge with merge anchors ## Merge with merge anchors
@ -213,14 +157,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -228,11 +171,6 @@ yq eval '.foobar * .foobarList' sample.yml
``` ```
will output will output
```yaml ```yaml
c: foobarList_c '': null
<<:
- *foo
- *bar
thing: foobar_thing
b: foobarList_b
``` ```

View File

@ -5,8 +5,8 @@ You can get the key/index of matching nodes by using the `path` operator to retu
## Map path ## Map path
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: cat}
b: cat '': null
``` ```
then then
```bash ```bash
@ -21,8 +21,8 @@ will output
## Get map key ## Get map key
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: cat}
b: cat '': null
``` ```
then then
```bash ```bash
@ -36,9 +36,8 @@ b
## Array path ## Array path
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [cat, dog]
- cat '': null
- dog
``` ```
then then
```bash ```bash
@ -53,9 +52,8 @@ will output
## Get array index ## Get array index
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [cat, dog]
- cat '': null
- dog
``` ```
then then
```bash ```bash
@ -69,10 +67,8 @@ will output
## Print path and value ## Print path and value
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: [cat, dog, frog]
- cat '': null
- dog
- frog
``` ```
then then
```bash ```bash
@ -80,13 +76,7 @@ yq eval '.a.[] | select(. == "*og") | [{"path":path, "value":.}]' sample.yml
``` ```
will output will output
```yaml ```yaml
- path: - '': null
- a - '': null
- 1
value: dog
- path:
- a
- 2
value: frog
``` ```

View File

@ -3,8 +3,8 @@ Pipe the results of an expression into another. Like the bash operator.
## Simple Pipe ## Simple Pipe
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: cat}
b: cat '': null
``` ```
then then
```bash ```bash
@ -21,6 +21,7 @@ Given a sample.yml file of:
a: cow a: cow
b: sheep b: sheep
c: same c: same
'': null
``` ```
then then
```bash ```bash
@ -31,5 +32,6 @@ will output
a: cat a: cat
b: dog b: dog
c: same c: same
'': null
``` ```

View File

@ -6,9 +6,9 @@ yq eval '.. style= "flow"' file.yaml
## Aliases are not traversed ## Aliases are not traversed
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: &cat a: &cat {c: frog}
c: frog
b: *cat b: *cat
'': null
``` ```
then then
```bash ```bash
@ -16,13 +16,10 @@ yq eval '[..]' sample.yml
``` ```
will output will output
```yaml ```yaml
- a: &cat - a: &cat {c: frog}
c: frog
b: *cat b: *cat
- &cat '': null
c: frog - null
- frog
- *cat
``` ```
## Merge docs are not traversed ## Merge docs are not traversed
@ -38,14 +35,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -56,8 +52,7 @@ will output
- c: foobar_c - c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
- foobar_c '': null
- *foo - null
- foobar_thing
``` ```

View File

@ -19,10 +19,8 @@ goat
## Select and update matching values in map ## Select and update matching values in map
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {things: cat, bob: goat, horse: dog}
things: cat '': null
bob: goat
horse: dog
``` ```
then then
```bash ```bash
@ -30,9 +28,7 @@ yq eval '(.a.[] | select(. == "*at")) |= "rabbit"' sample.yml
``` ```
will output will output
```yaml ```yaml
a: a: {things: rabbit, bob: rabbit, horse: dog}
things: rabbit '': null
bob: rabbit
horse: dog
``` ```

View File

@ -14,6 +14,7 @@ Given a sample.yml file of:
c: frog c: frog
a: blah a: blah
b: bing b: bing
'': null
``` ```
then then
```bash ```bash
@ -21,6 +22,7 @@ yq eval 'sortKeys(.)' sample.yml
``` ```
will output will output
```yaml ```yaml
'': null
a: blah a: blah
b: bing b: bing
c: frog c: frog
@ -31,19 +33,9 @@ Note the array elements are left unsorted, but maps inside arrays are sorted
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
bParent: bParent: {c: dog, array: [3, 1, 2]}
c: dog aParent: {z: donkey, x: [{c: yum, b: delish}, {b: ew, a: apple}]}
array: '': null
- 3
- 1
- 2
aParent:
z: donkey
x:
- c: yum
b: delish
- b: ew
a: apple
``` ```
then then
```bash ```bash
@ -51,18 +43,8 @@ yq eval 'sortKeys(..)' sample.yml
``` ```
will output will output
```yaml ```yaml
aParent: '': null
x: aParent: {z: donkey, x: [{c: yum, b: delish}, {b: ew, a: apple}]}
- b: delish bParent: {c: dog, array: [3, 1, 2]}
c: yum
- a: apple
b: ew
z: donkey
bParent:
array:
- 3
- 1
- 2
c: dog
``` ```

View File

@ -6,6 +6,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
then then
```bash ```bash
@ -14,10 +15,11 @@ yq eval '.. style="tagged"' sample.yml
will output will output
```yaml ```yaml
!!map !!map
a: !!str cat a: cat
b: !!int 5 b: 5
c: !!float 3.2 c: 3.2
e: !!bool true e: true
'': !!null null
``` ```
## Set double quote style ## Set double quote style
@ -27,6 +29,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
then then
```bash ```bash
@ -34,10 +37,11 @@ yq eval '.. style="double"' sample.yml
``` ```
will output will output
```yaml ```yaml
a: "cat" a: cat
b: "5" b: 5
c: "3.2" c: 3.2
e: "true" e: true
'': "null"
``` ```
## Set single quote style ## Set single quote style
@ -47,6 +51,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
then then
```bash ```bash
@ -54,10 +59,11 @@ yq eval '.. style="single"' sample.yml
``` ```
will output will output
```yaml ```yaml
a: 'cat' a: cat
b: '5' b: 5
c: '3.2' c: 3.2
e: 'true' e: true
'': 'null'
``` ```
## Set literal quote style ## Set literal quote style
@ -67,6 +73,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
then then
```bash ```bash
@ -74,14 +81,12 @@ yq eval '.. style="literal"' sample.yml
``` ```
will output will output
```yaml ```yaml
a: |- a: cat
cat b: 5
b: |- c: 3.2
5 e: true
c: |- '': |-
3.2 null
e: |-
true
``` ```
## Set folded quote style ## Set folded quote style
@ -91,6 +96,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
then then
```bash ```bash
@ -98,14 +104,12 @@ yq eval '.. style="folded"' sample.yml
``` ```
will output will output
```yaml ```yaml
a: >- a: cat
cat b: 5
b: >- c: 3.2
5 e: true
c: >- '': >-
3.2 null
e: >-
true
``` ```
## Set flow quote style ## Set flow quote style
@ -115,6 +119,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
then then
```bash ```bash
@ -122,7 +127,7 @@ yq eval '.. style="flow"' sample.yml
``` ```
will output will output
```yaml ```yaml
{a: cat, b: 5, c: 3.2, e: true} {a: cat, b: 5, c: 3.2, e: true, '': null}
``` ```
## Pretty print ## Pretty print
@ -134,6 +139,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
then then
```bash ```bash
@ -145,6 +151,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
## Read style ## Read style
@ -159,7 +166,6 @@ yq eval '.. | style' sample.yml
will output will output
```yaml ```yaml
flow flow
double
single
``` ```

View File

@ -7,6 +7,7 @@ b: 5
c: 3.2 c: 3.2
e: true e: true
f: [] f: []
'': null
``` ```
then then
```bash ```bash
@ -15,11 +16,7 @@ yq eval '.. | tag' sample.yml
will output will output
```yaml ```yaml
!!map !!map
!!str !!null
!!int
!!float
!!bool
!!seq
``` ```
## Convert numbers to strings ## Convert numbers to strings
@ -29,6 +26,7 @@ a: cat
b: 5 b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```
then then
```bash ```bash
@ -37,8 +35,9 @@ yq eval '(.. | select(tag == "!!int")) tag= "!!str"' sample.yml
will output will output
```yaml ```yaml
a: cat a: cat
b: "5" b: 5
c: 3.2 c: 3.2
e: true e: true
'': null
``` ```

View File

@ -2,8 +2,8 @@ This is the simplest (and perhaps most used) operator, it is used to navigate de
## Simple map navigation ## Simple map navigation
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {b: apple}
b: apple '': null
``` ```
then then
```bash ```bash
@ -11,7 +11,7 @@ yq eval '.a' sample.yml
``` ```
will output will output
```yaml ```yaml
b: apple {b: apple}
``` ```
## Splat ## Splat
@ -20,7 +20,9 @@ Often used to pipe children into other operators
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
- b: apple - b: apple
'': null
- c: banana - c: banana
'': null
``` ```
then then
```bash ```bash
@ -29,7 +31,9 @@ yq eval '.[]' sample.yml
will output will output
```yaml ```yaml
b: apple b: apple
'': null
c: banana c: banana
'': null
``` ```
## Special characters ## Special characters
@ -38,6 +42,7 @@ Use quotes around path elements with special characters
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
"{}": frog "{}": frog
'': null
``` ```
then then
```bash ```bash
@ -54,6 +59,7 @@ Nodes are added dynamically while traversing
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
c: banana c: banana
'': null
``` ```
then then
```bash ```bash
@ -67,9 +73,8 @@ null
## Wildcard matching ## Wildcard matching
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: a: {cat: apple, mad: things}
cat: apple '': null
mad: things
``` ```
then then
```bash ```bash
@ -84,9 +89,9 @@ things
## Aliases ## Aliases
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: &cat a: &cat {c: frog}
c: frog
b: *cat b: *cat
'': null
``` ```
then then
```bash ```bash
@ -100,9 +105,9 @@ will output
## Traversing aliases with splat ## Traversing aliases with splat
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: &cat a: &cat {c: frog}
c: frog
b: *cat b: *cat
'': null
``` ```
then then
```bash ```bash
@ -116,9 +121,9 @@ frog
## Traversing aliases explicitly ## Traversing aliases explicitly
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: &cat a: &cat {c: frog}
c: frog
b: *cat b: *cat
'': null
``` ```
then then
```bash ```bash
@ -149,6 +154,7 @@ will output
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
2: cat 2: cat
'': null
``` ```
then then
```bash ```bash
@ -156,13 +162,13 @@ yq eval '.[2]' sample.yml
``` ```
will output will output
```yaml ```yaml
cat
``` ```
## Maps with non existing numeric keys ## Maps with non existing numeric keys
Given a sample.yml file of: Given a sample.yml file of:
```yaml ```yaml
a: b a: b
'': null
``` ```
then then
```bash ```bash
@ -170,7 +176,6 @@ yq eval '.[0]' sample.yml
``` ```
will output will output
```yaml ```yaml
null
``` ```
## Traversing merge anchors ## Traversing merge anchors
@ -186,14 +191,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -217,14 +221,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -248,14 +251,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -279,14 +281,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -294,8 +295,8 @@ yq eval '.foobar.[]' sample.yml
``` ```
will output will output
```yaml ```yaml
foo_c foobar_c
foo_a *foo
foobar_thing foobar_thing
``` ```
@ -314,14 +315,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -345,14 +345,13 @@ bar: &bar
c: bar_c c: bar_c
foobarList: foobarList:
b: foobarList_b b: foobarList_b
!!merge <<: !!merge <<: [*foo, *bar]
- *foo
- *bar
c: foobarList_c c: foobarList_c
foobar: foobar:
c: foobar_c c: foobar_c
!!merge <<: *foo !!merge <<: *foo
thing: foobar_thing thing: foobar_thing
'': null
``` ```
then then
```bash ```bash
@ -360,9 +359,8 @@ yq eval '.foobarList.[]' sample.yml
``` ```
will output will output
```yaml ```yaml
bar_b foobarList_b
foo_a [*foo, *bar]
bar_thing
foobarList_c foobarList_c
``` ```

View File

@ -17,6 +17,7 @@ Given a sample.yml file of:
a: fieldA a: fieldA
b: fieldB b: fieldB
c: fieldC c: fieldC
'': null
``` ```
then then
```bash ```bash

View File

@ -65,7 +65,7 @@ var SortKeys = &OperationType{Type: "SORT_KEYS", NumArgs: 1, Precedence: 50, Han
var CollectObject = &OperationType{Type: "COLLECT_OBJECT", NumArgs: 0, Precedence: 50, Handler: CollectObjectOperator} var CollectObject = &OperationType{Type: "COLLECT_OBJECT", NumArgs: 0, Precedence: 50, Handler: CollectObjectOperator}
var TraversePath = &OperationType{Type: "TRAVERSE_PATH", NumArgs: 0, Precedence: 50, Handler: TraversePathOperator} var TraversePath = &OperationType{Type: "TRAVERSE_PATH", NumArgs: 0, Precedence: 50, Handler: TraversePathOperator}
var TraverseArray = &OperationType{Type: "TRAVERSE_ARRAY", NumArgs: 2, Precedence: 50, Handler: TraverseArrayOperator} var TraverseArray = &OperationType{Type: "TRAVERSE_ARRAY", NumArgs: 1, Precedence: 50, Handler: TraverseArrayOperator}
var DocumentFilter = &OperationType{Type: "DOCUMENT_FILTER", NumArgs: 0, Precedence: 50, Handler: TraversePathOperator} var DocumentFilter = &OperationType{Type: "DOCUMENT_FILTER", NumArgs: 0, Precedence: 50, Handler: TraversePathOperator}
var SelfReference = &OperationType{Type: "SELF", NumArgs: 0, Precedence: 50, Handler: SelfOperator} var SelfReference = &OperationType{Type: "SELF", NumArgs: 0, Precedence: 50, Handler: SelfOperator}

View File

@ -12,11 +12,6 @@ func TraverseArrayOperator(d *dataTreeNavigator, matchingNodes *list.List, pathN
// lhs is an expression that will yield a bunch of arrays // lhs is an expression that will yield a bunch of arrays
// rhs is a collect expression that will yield indexes to retreive of the arrays // rhs is a collect expression that will yield indexes to retreive of the arrays
lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
if err != nil {
return nil, err
}
rhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Rhs) rhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Rhs)
if err != nil { if err != nil {
return nil, err return nil, err
@ -25,36 +20,89 @@ func TraverseArrayOperator(d *dataTreeNavigator, matchingNodes *list.List, pathN
var indicesToTraverse = rhs.Front().Value.(*CandidateNode).Node.Content var indicesToTraverse = rhs.Front().Value.(*CandidateNode).Node.Content
var matchingNodeMap = list.New() var matchingNodeMap = list.New()
for el := lhs.Front(); el != nil; el = el.Next() { for el := matchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode) candidate := el.Value.(*CandidateNode)
node := UnwrapDoc(candidate.Node)
if node.Tag == "!!null" {
log.Debugf("OperatorArrayTraverse got a null - turning it into an empty array")
// auto vivification, make it into an empty array
node.Tag = ""
node.Kind = yaml.SequenceNode
} else if node.Kind == yaml.AliasNode {
candidate.Node = node.Alias
node = node.Alias
}
if candidate.Node.Kind == yaml.SequenceNode { if node.Kind == yaml.SequenceNode {
newNodes, err := traverseArrayWithIndices(candidate, indicesToTraverse) newNodes, err := traverseArrayWithIndices(candidate, indicesToTraverse)
if err != nil { if err != nil {
return nil, err return nil, err
} }
matchingNodeMap.PushBackList(newNodes) matchingNodeMap.PushBackList(newNodes)
} else if node.Kind == yaml.MappingNode && len(indicesToTraverse) == 0 {
// splat the map
newNodes, err := traverseMapWithIndices(candidate, indicesToTraverse)
if err != nil {
return nil, err
}
matchingNodeMap.PushBackList(newNodes)
} else { } else {
log.Debugf("OperatorArray Traverse skipping %v as its a %v", candidate, candidate.Node.Tag) log.Debugf("OperatorArrayTraverse skipping %v as its a %v", candidate, node.Tag)
} }
} }
return matchingNodeMap, nil return matchingNodeMap, nil
} }
func traverseMapWithIndices(candidate *CandidateNode, indices []*yaml.Node) (*list.List, error) {
//REWRITE TO USE TRAVERSE MAP
node := UnwrapDoc(candidate.Node)
var contents = node.Content
var matchingNodeMap = list.New()
if len(indices) == 0 {
for index := 0; index < len(contents); index = index + 2 {
key := contents[index]
value := contents[index+1]
matchingNodeMap.PushBack(&CandidateNode{
Node: value,
Path: candidate.CreateChildPath(key.Value),
Document: candidate.Document,
})
}
return matchingNodeMap, nil
}
for index := 0; index < len(contents); index = index + 2 {
key := contents[index]
value := contents[index+1]
for _, indexNode := range indices {
if key.Value == indexNode.Value {
matchingNodeMap.PushBack(&CandidateNode{
Node: value,
Path: candidate.CreateChildPath(key.Value),
Document: candidate.Document,
})
}
}
}
return matchingNodeMap, nil
}
func traverseArrayWithIndices(candidate *CandidateNode, indices []*yaml.Node) (*list.List, error) { func traverseArrayWithIndices(candidate *CandidateNode, indices []*yaml.Node) (*list.List, error) {
log.Debug("traverseArrayWithIndices") log.Debug("traverseArrayWithIndices")
var newMatches = list.New() var newMatches = list.New()
node := UnwrapDoc(candidate.Node)
if len(indices) == 0 { if len(indices) == 0 {
var contents = candidate.Node.Content
var index int64 var index int64
for index = 0; index < int64(len(contents)); index = index + 1 { for index = 0; index < int64(len(node.Content)); index = index + 1 {
newMatches.PushBack(&CandidateNode{ newMatches.PushBack(&CandidateNode{
Document: candidate.Document, Document: candidate.Document,
Path: candidate.CreateChildPath(index), Path: candidate.CreateChildPath(index),
Node: contents[index], Node: node.Content[index],
}) })
} }
return newMatches, nil return newMatches, nil
@ -67,10 +115,10 @@ func traverseArrayWithIndices(candidate *CandidateNode, indices []*yaml.Node) (*
return nil, err return nil, err
} }
indexToUse := index indexToUse := index
contentLength := int64(len(candidate.Node.Content)) contentLength := int64(len(node.Content))
for contentLength <= index { for contentLength <= index {
candidate.Node.Content = append(candidate.Node.Content, &yaml.Node{Tag: "!!null", Kind: yaml.ScalarNode, Value: "null"}) node.Content = append(node.Content, &yaml.Node{Tag: "!!null", Kind: yaml.ScalarNode, Value: "null"})
contentLength = int64(len(candidate.Node.Content)) contentLength = int64(len(node.Content))
} }
if indexToUse < 0 { if indexToUse < 0 {
@ -82,7 +130,7 @@ func traverseArrayWithIndices(candidate *CandidateNode, indices []*yaml.Node) (*
} }
newMatches.PushBack(&CandidateNode{ newMatches.PushBack(&CandidateNode{
Node: candidate.Node.Content[indexToUse], Node: node.Content[indexToUse],
Document: candidate.Document, Document: candidate.Document,
Path: candidate.CreateChildPath(index), Path: candidate.CreateChildPath(index),
}) })

View File

@ -5,6 +5,22 @@ import (
) )
var traverseArrayOperatorScenarios = []expressionScenario{ var traverseArrayOperatorScenarios = []expressionScenario{
{
document: `[a,b,c]`,
expression: `.[]`,
expected: []string{
"D0, P[0], (!!str)::a\n",
"D0, P[1], (!!str)::b\n",
"D0, P[2], (!!str)::c\n",
},
},
{
document: `[a,b,c]`,
expression: `[]`,
expected: []string{
"D0, P[], (!!seq)::[]\n",
},
},
{ {
document: `{a: [a,b,c]}`, document: `{a: [a,b,c]}`,
expression: `.a[0]`, expression: `.a[0]`,
@ -20,6 +36,14 @@ var traverseArrayOperatorScenarios = []expressionScenario{
"D0, P[a 2], (!!str)::c\n", "D0, P[a 2], (!!str)::c\n",
}, },
}, },
{
document: `{a: [a,b,c]}`,
expression: `.a.[0, 2]`,
expected: []string{
"D0, P[a 0], (!!str)::a\n",
"D0, P[a 2], (!!str)::c\n",
},
},
{ {
document: `{a: [a,b,c]}`, document: `{a: [a,b,c]}`,
expression: `.a.[0]`, expression: `.a.[0]`,

View File

@ -80,6 +80,14 @@ var assignOperatorScenarios = []expressionScenario{
{ {
description: "Update selected results", description: "Update selected results",
document: `{a: {b: apple, c: cactus}}`, document: `{a: {b: apple, c: cactus}}`,
expression: `(.a[] | select(. == "apple")) = "frog"`,
expected: []string{
"D0, P[], (doc)::{a: {b: frog, c: cactus}}\n",
},
},
{
skipDoc: true,
document: `{a: {b: apple, c: cactus}}`,
expression: `(.a.[] | select(. == "apple")) = "frog"`, expression: `(.a.[] | select(. == "apple")) = "frog"`,
expected: []string{ expected: []string{
"D0, P[], (doc)::{a: {b: frog, c: cactus}}\n", "D0, P[], (doc)::{a: {b: frog, c: cactus}}\n",

View File

@ -77,7 +77,7 @@ func traverse(d *dataTreeNavigator, matchingNode *CandidateNode, operation *Oper
} }
func keyMatches(key *yaml.Node, pathNode *Operation) bool { func keyMatches(key *yaml.Node, pathNode *Operation) bool {
return pathNode.Value == "[]" || Match(key.Value, pathNode.StringValue) return Match(key.Value, pathNode.StringValue)
} }
func traverseMap(matchingNode *CandidateNode, operation *Operation) (*list.List, error) { func traverseMap(matchingNode *CandidateNode, operation *Operation) (*list.List, error) {

View File

@ -65,7 +65,7 @@ var traversePathOperatorScenarios = []expressionScenario{
}, },
{ {
skipDoc: true, skipDoc: true,
document: `{}`, document: ``,
expression: `.[1].a`, expression: `.[1].a`,
expected: []string{ expected: []string{
"D0, P[1 a], (!!null)::null\n", "D0, P[1 a], (!!null)::null\n",

View File

@ -17,6 +17,11 @@ var pathTests = []struct {
append(make([]interface{}, 0), "[", "]"), append(make([]interface{}, 0), "[", "]"),
append(make([]interface{}, 0), "EMPTY", "COLLECT", "SHORT_PIPE"), append(make([]interface{}, 0), "EMPTY", "COLLECT", "SHORT_PIPE"),
}, },
{
`.[]`,
append(make([]interface{}, 0), "TRAVERSE_ARRAY", "[", "]"),
append(make([]interface{}, 0), "EMPTY", "COLLECT", "SHORT_PIPE", "TRAVERSE_ARRAY"),
},
{ {
`.a[]`, `.a[]`,
append(make([]interface{}, 0), "a", "TRAVERSE_ARRAY", "[", "]"), append(make([]interface{}, 0), "a", "TRAVERSE_ARRAY", "[", "]"),

View File

@ -22,6 +22,7 @@ const (
CloseCollect CloseCollect
OpenCollectObject OpenCollectObject
CloseCollectObject CloseCollectObject
TraverseArrayCollect
) )
type Token struct { type Token struct {
@ -48,6 +49,9 @@ func (t *Token) toString() string {
return "{" return "{"
} else if t.TokenType == CloseCollectObject { } else if t.TokenType == CloseCollectObject {
return "}" return "}"
} else if t.TokenType == TraverseArrayCollect {
return ".["
} else { } else {
return "NFI" return "NFI"
} }
@ -185,7 +189,8 @@ func initLexer() (*lex.Lexer, error) {
lexer.Add([]byte(`\(`), literalToken(OpenBracket, false)) lexer.Add([]byte(`\(`), literalToken(OpenBracket, false))
lexer.Add([]byte(`\)`), literalToken(CloseBracket, true)) lexer.Add([]byte(`\)`), literalToken(CloseBracket, true))
lexer.Add([]byte(`\.\[\]`), pathToken(false)) // lexer.Add([]byte(`\.\[\]`), pathToken(false)) // traverseCollect(false)
lexer.Add([]byte(`\.\[`), literalToken(TraverseArrayCollect, false))
lexer.Add([]byte(`\.\.`), opToken(RecursiveDescent)) lexer.Add([]byte(`\.\.`), opToken(RecursiveDescent))
lexer.Add([]byte(`,`), opToken(Union)) lexer.Add([]byte(`,`), opToken(Union))
@ -228,7 +233,7 @@ func initLexer() (*lex.Lexer, error) {
lexer.Add([]byte(`\s*\|=\s*`), opTokenWithPrefs(Assign, nil, &AssignOpPreferences{true})) lexer.Add([]byte(`\s*\|=\s*`), opTokenWithPrefs(Assign, nil, &AssignOpPreferences{true}))
lexer.Add([]byte(`\.\[-?[0-9]+\]`), arrayIndextoken(true)) // lexer.Add([]byte(`\.\[-?[0-9]+\]`), arrayIndextoken(true)) // traverseCollect(true)
lexer.Add([]byte("( |\t|\n|\r)+"), skip) lexer.Add([]byte("( |\t|\n|\r)+"), skip)
@ -320,6 +325,17 @@ func (p *pathTokeniser) handleToken(tokens []*Token, index int, postProcessedTok
skipNextToken = false skipNextToken = false
token := tokens[index] token := tokens[index]
if token.TokenType == TraverseArrayCollect {
//need to put a traverse array then a collect token
// do this by adding traverse then converting token to collect
op := &Operation{OperationType: TraverseArray, StringValue: "TRAVERSE_ARRAY"}
postProcessedTokens = append(postProcessedTokens, &Token{TokenType: OperationToken, Operation: op})
token = &Token{TokenType: OpenCollect}
}
if index != len(tokens)-1 && token.AssignOperation != nil && if index != len(tokens)-1 && token.AssignOperation != nil &&
tokens[index+1].TokenType == OperationToken && tokens[index+1].TokenType == OperationToken &&
tokens[index+1].Operation.OperationType == Assign { tokens[index+1].Operation.OperationType == Assign {
@ -337,8 +353,19 @@ func (p *pathTokeniser) handleToken(tokens []*Token, index int, postProcessedTok
} }
if index != len(tokens)-1 && token.CheckForPostTraverse && if index != len(tokens)-1 && token.CheckForPostTraverse &&
tokens[index+1].TokenType == OpenCollect { tokens[index+1].TokenType == OpenCollect {
op := &Operation{OperationType: TraverseArray}
op := &Operation{OperationType: ShortPipe, Value: "PIPE"}
postProcessedTokens = append(postProcessedTokens, &Token{TokenType: OperationToken, Operation: op}) postProcessedTokens = append(postProcessedTokens, &Token{TokenType: OperationToken, Operation: op})
op = &Operation{OperationType: TraverseArray}
postProcessedTokens = append(postProcessedTokens, &Token{TokenType: OperationToken, Operation: op})
}
if index != len(tokens)-1 && token.CheckForPostTraverse &&
tokens[index+1].TokenType == TraverseArrayCollect {
op := &Operation{OperationType: ShortPipe, Value: "PIPE"}
postProcessedTokens = append(postProcessedTokens, &Token{TokenType: OperationToken, Operation: op})
} }
return postProcessedTokens, skipNextToken return postProcessedTokens, skipNextToken
} }