3

Given a YAML file, example.yaml:

node:
  sub_node:
    get_this:

I'd like to get a variable containing get_this using Mike Farah's yq and the string sub_node

yaml="$(cat example.yaml)"
nodename=sub_node
sub_yaml= "$(echo "$yaml" | yq -r '.$nodename' )";
# also tried -> sub_yaml= "$(echo "$yaml" | yq -r '.'"$nodename" )";

Note this is a contrived example, in reality, the sub_node string is not known in advance so I need to substitute the $nodename string.

I can't seem to figure out how to escape out of the single quote query string required by yq.

How might I do this?

4
  • 3
    What is the difference between the "...", '...', $'...', and $"..." quotes in the shell?. Double-quotes expand shell variables, single quotes don't. So '.$nodename' will pass the string .$nodename, while ".$nodename", will pass the string .sub_node as the argument to yq.
    – ilkkachu
    Commented Mar 13, 2023 at 11:50
  • 1
    At least with kislyuk's yq, you can pass variables in the same way you would to jq natively i.e. using --arg or --argjson / $ARGS.named Commented Mar 13, 2023 at 12:17
  • Do we need a yq tag at U&L? Better use the YAML tag.
    – Philippos
    Commented Mar 13, 2023 at 12:31
  • @Philippos I was unsure whether to add it. Have done as suggested.
    – Lee
    Commented Mar 13, 2023 at 12:32

2 Answers 2

5

With Mike Farah's yq, you can get the value of the nodename shell variable into your yq expression as part of a path by accessing it from the utility's environment using the strenv() function, like so:

$ nodename='sub_node' yq '.node[strenv(nodename)]' example.yaml
get_this:

This accesses the subsection of the top-level node key given by the value of the nodename environment variable.

This avoids injecting the value of a shell variable into the yq expression, which means that you can access sections with dots and other special characters in their names.


Using Andrey Kislyuk's yq, a similar thing may be done by either passing the sub-key via an internal variable, like so:

$ nodename=sub_node
$ yq -y --arg sect "$nodename" '.node[$sect]' example.yaml
get_this: null

... or by reading the value from the environment,

$ nodename=sub_node yq -y '.node[$ENV.nodename]' example.yaml
get_this: null
2
  • Per the guide at mikefarah.gitbook.io/yq it's strenv(var), not env(var). Commented Apr 23 at 17:05
  • 1
    @JohnMichelau Yeah, although it seems to work with env(), it appears strenv() is for strings specifically. Answer updated. Thanks.
    – Kusalananda
    Commented Apr 23 at 17:30
0

As stated in ikkachu's comment, I should be using double quotes.

Ironically, it turns out that none of my trial and error efforts were working anyway due to the space I had after =.

I also had to correct the lookup string for the above example:

nodename=node.sub_node
sub_yaml="$(echo "$yaml" | yq -r ".$nodename" )";
echo $sub_yaml
get_this:

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .