Karl
Karl

Reputation: 5822

How to use `yq` to select key-value pairs and format them into "$key=$value" style outputs?

Let say I have YAML file that looks like this:

FOO: somefoo
BAR: somebar

I would like to convert this (using yq) into the following so that I can source the contents into environment variables:

export BAR='somebar'
export FOO='somefoo'

I can do it it with jq by converting the input to JSON first, but I can't seem to figure out how to do it with yq only. (I am using yq 4.x, <4.18).

So, concretely, how could I do the following using just yq?

INPUT="FOO: somefoo
BAR: somebar"

echo "$INPUT" | yq e 'to_json' - | jq -r 'keys[] as $k | "export \($k)='\''\(.[$k])'\''"'

Upvotes: 4

Views: 6375

Answers (3)

tlwhitec
tlwhitec

Reputation: 2453

The @sh operator has been added in yq v4.31.1 (with my humble contribution). Now you can do it pretty much the same way as in jq:

yq '.[] | "export " + key + "=" + @sh'

The quoting algorithm is a bit different from jq as it starts to quote only at characters that need quoting, so the literal output will likely differ, but will be later parsed equally.

# input
FOO: somefoo
BAR: somebar and some
# result
export FOO=somefoo
export BAR=somebar' and some'

With older yq versions you can still implement a primitive but safe quoting algorithm using other yq functions (the quoting is a little lovely nightmare, though):

# POSIX shell quoting starting "
yq ".[] | \"export \" + key + \"='\" + sub(\"'\", \"'\''\") + \"'\""
# POSIX shell quoting starting '
yq '.[] | "export " + key + "='\''" + sub("'\''", "'\'\\\'\''") + "'\''"'
# BASH "dollar" quoting
yq $'.[] | "export " + key + "=\'" + sub("\'", "\'\\\'\'") + "\'"'

Actually this is exactly what jq does with its @sh. In all cases this ends up as:

export FOO='somefoo'
export BAR='somebar and some'

Upvotes: 2

David Ongaro
David Ongaro

Reputation: 3937

Use the key operator and string concatenation:

$ echo "$INPUT" | yq $'.[] | "export " + key + "=\'" + . + "\'"'
export FOO='somefoo'
export BAR='somebar'

Tested with yq 4.27.2

Upvotes: 1

pmf
pmf

Reputation: 36033

You could switch to kislyuk's yq which uses native jq under the hood. Then, you would just need to_entries to access key and value, string interpolation in combination with the -r flag to produce the output, and @sh to escape for shell compliance:

yq -r 'to_entries[] | "export \(.key)=\(.value | @sh)"'
export FOO='somefoo'
export BAR='somebar'

Upvotes: 5

Related Questions