I have a yaml file with the following format
---
users:
foo1.bar1#email.com:
- roles/role1
- roles/role2
- roles/role3
foo2.bar2#email.com:
- roles/role4
- roles/role5
- roles/role6
Now I would like to print the roles for foo1.bar1#email.com
Im trying to do the following
cat permissions.yaml | yq '.users[ foo1.bar1#email.com]'
jq: error: syntax error, unexpected FORMAT (Unix shell quoting issues?) at <top-level>, line 1:
.users[ foo1.bar1#email.com]
jq: 1 compile error
Is there a work around to this ?
If you are using v3 (or later) of mikefarah/yq you can escape keys with quotes, like this:
cat permissions.yaml | yq e '.users."foo1.bar1#email.com"' -
or
cat permissions.yaml | yq e '.users["foo1.bar1#email.com"]' -
Documented in v3 here and in v4 here.
I verified this with v4.13.4:
$ yq --version
yq (https://github.com/mikefarah/yq/) version 4.13.4
Try removing the whitespace in front of your key:
cat permissions.yaml | yq '.users[foo1.bar1#email.com]'
That might resolve it.
Related
I have the following map of strings and I would like to change the value of "image.tag" key .
I tried the following but it does not work as I expected. The problem here is that image.tag is a string but I am not sure how to express that. Thanks
yq eval --inplace ".spec.chart.values.\"image.tag\": \"$TAG\"" values.yaml
spec:
chart:
values:
image.tag: master
You don't have to use double quotes for reading variables from shell. mikefarah/yq provides a method strenv to load variables (also environment) form the shell.
Also by using single quotes, you can just wrap image.tag under double quotes to let it be treated as a single word.
Use the style method to set quotes for the updated value style="double" reflects the updated tag value to be treated as a string.
newtag="foo" yq e --inplace '.spec.chart.values."image.tag" |= strenv(newtag) | ..style="double"' values.yaml
or if the new tag is defined as a shell variable say TAG
newtag="$TAG" yq e --inplace '.spec.chart.values."image.tag" |= strenv(newtag) | ..style="double"' values.yaml
Note that, if you are using yq version above 4.18.1, the eval action e is the default one and can be skipped altogether.
I have an ansible playbook, which first initializes a fact using set_fact, and then a task that consumes the fact and generates a YAML file from it.
The playbook looks like this
- name: Test yaml output
hosts: localhost
become: true
tasks:
- name: set config
set_fact:
config:
A12345: '00000000000000000000000087895423'
A12352: '00000000000000000000000087565857'
A12353: '00000000000000000000000031200527'
- name : gen yaml file
copy:
dest: "a.yaml"
content: "{{ config | to_nice_yaml }}"
Actual Output
When I run the playbook, the output in a.yaml is
A12345: 00000000000000000000000087895423
A12352: 00000000000000000000000087565857
A12353: '00000000000000000000000031200527'
Notice only the last line has the value in quotes
Expected Output
The expected output is
A12345: '00000000000000000000000087895423'
A12352: '00000000000000000000000087565857'
A12353: '00000000000000000000000031200527'
All values should be quoted.
I cannot, for the life of me, figure out why only the last line has the value printed in single-quotes.
I've tried this with Ansible version 2.7.7, and version 2.11.12, both running against Python 3.7.3. The behavior is the same.
It's because 031200527 is an octal number, whereas 087895423 is not, thus, the octal scalar needs quoting but the other values do not because the leading zeros are interpreted in yaml exactly the same way 00hello would be -- just the ascii 0 followed by other ascii characters
If it really bothers you that much, and having quoted scalars is obligatory for some reason, to_nice_yaml accepts the same kwargs as does pyyaml.dump:
- debug:
msg: '{{ thing | to_nice_yaml(default_style=quote) }}'
vars:
quote: "'"
thing:
A1234: '008123'
A2345: '003123'
which in this case will also quote the keys, but unconditionally quotes the scalars
Given the following example.yaml definition:
shop:
europe:
germany:
shopA: shopBAddress
asia:
thailand:
shopB:
address: shopBAddress
I try to access shop.europe.germany path with use of env operator.
However when I do that I get error:
location=europe country=germany yq e '.shop.[env(location)].[env(country)]' example.yaml
Error: Bad expression, please check expression syntax
location=europe country=germany yq e '.shop.[env(location)][env(country)]' exmaple.yaml
Error: Cannot index array with 'germany' (strconv.ParseInt: parsing "germany": invalid syntax)
What am I doing wrong here?
Your idea is right, but between two env(..) expressions or preceding one, you don't need the . operator, i.e. the below should work (verfied on version 4.11.2)
location=europe country=germany yq e '.shop[env(location)][env(country)]' yaml
I'm trying to use yq https://github.com/mikefarah/yq v4.3.2 to add a yaml value in a CloudFormation template like so:
Mappings:
RegionMap:
us-east-1:
AMI: 'ami-YeahRight'
Instead, what I'm getting is:
Mappings:
RegionMap:
us-east-1:
AMI: ami-YeahRight
The style bits in the documentation and from this SO answer yq processing a string with quotation marks made me think that this portion of a bash script would work however the style portion is ignored.
region="us-east-1"
ami="ami-YeahRight"
echo Inserting $ami into $region
yq eval '.Mappings.RegionMap.'"$region"'.AMI='"$ami"' style="single"' -i temp.yaml
I've tried a whole bunch of similar bits but can't seem to crack this nut. Any help here would be greatly appreciated!
mikefaraq/yq is going through major leap of changes starting from v4 and I'm not surprised that things are breaking in-between.
On v4.4 I can make this work, but using env() function to look-up the variables and use the ..style attribute to set the quoting style
region="us-east-1" ami="ami-YeahRight" yq e '.Mappings.RegionMap.[env(region)] = env(ami) | ..style="single"' yaml
I have a yaml file that looks something like this:
a:
desc:
value: 1
b:
desc:
value: 2
# ...
I want to convert it to this:
a: 1
b: 2
# ...
In yq v2, I used the command .[] |= .value' to update each element of the array to the value in the .value field. Is there a way to do this with yq v3?
cat config.yaml | yq w - "*" "*.value"
yields
a: *.value
b: *.value
# ...
``
Your claim seems to be contradicting each other. There are two versions of yq implementations out there. A python implementation as a wrapper over jq and other written in Go.. See my answer that covers in details about those versions.
When you said you used .[] |= .value in yq v2, that's actually not the Go version, but the version with the Python wrapper over jq, since that syntax matches its DSL. But the other attempt yq w - "*" "*.value" seems to be the actual Go version.
Since there is an uncertainty around which version of yq in installed for you, I'll try to provide my view in both the versions
kislyuk's yq
yq -y '.[] |= .value' yaml
mikefarah's yq
The Go version does not have dynamic transformational capabilities like its Python version and does not support this type of update directly. Because the write/new field creations syntax is simply
yq w <yaml_file> <path_expression> <new value>
where the new value is not an expression but a literal value. Had it supported expressions, we could have conjured up a way to do the transformation. The Go version is otherwise good, but lacking support in some key transformational capabilities.
P.S. I've raised a GitHub feature request to allow such transformations. See https://github.com/mikefarah/yq/issues/602
As of today Dec 21st, 2020, yq v4 is in beta and supports this transformation. Download the v4 version and try
yq eval '.[] |= .value' test.yml