1

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?

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
Lee
  • 471
  • 3
  • 5
  • 15
  • 3
    [What is the difference between the "...", '...', $'...', and $"..." quotes in the shell?](https://unix.stackexchange.com/questions/503013/what-is-the-difference-between-the-and-quotes-in-th). 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 Mar 13 '23 at 11:50
  • 1
    At least with [kislyuk's yq](https://github.com/kislyuk/yq), you can pass variables in the same way you would to jq natively i.e. using `--arg` or `--argjson` / `$ARGS.named` – steeldriver Mar 13 '23 at 12:17
  • Do we need a `yq` tag at U&L? Better use the `YAML` tag. – Philippos Mar 13 '23 at 12:31
  • @Philippos I was unsure whether to add it. Have done as suggested. – Lee Mar 13 '23 at 12:32

2 Answers2

3

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 env() function, like so:

$ nodename='sub_node' yq '.node[env(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
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
-1

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:
Lee
  • 471
  • 3
  • 5
  • 15