0

I have one yaml file named file.yaml

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: dashboarding-route
spec:
  host: dashboarding-route.domain
  port:
    targetPort: 100
  tls:
    termination: passthrough
  to:
    kind: Service
    name: dashboarding

Then I run this command

template=$(cat "file.yaml" | sed "s/domain/$MYVARVALUE/g")

MYVARVALUE variable value can be anything.

after executing this I want value of template variable in same structure as a yaml file. For Ex. when I do echo $template the out put I want is

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: dashboarding-route
spec:
  host: dashboarding-route.domain
  port:
    targetPort: 100
  tls:
    termination: passthrough
  to:
    kind: Service
    name: dashboarding

Can anyone please help me in this problem?

Dhanu
  • 31
  • 3
  • 2
    Doesn't quote i.e. `echo "$template"` output what you need? – Taylor G. Feb 22 '23 at 05:49
  • See ["I just assigned a variable, but `echo $variable` shows something else"](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) and ["When should I double-quote a parameter expansion?"](https://stackoverflow.com/questions/55023461/when-should-i-double-quote-a-parameter-expansion) (short answer: almost always). – Gordon Davisson Feb 22 '23 at 05:53

1 Answers1

1

Solution1: "just use plain echo with double-quotes around the variable" -Gordon Davidson

$: MYVARVALUE=some-new-domain
$: template=$(cat "file.yaml" | sed "s/domain/$MYVARVALUE/g")
$: echo "$template"

Which gives the following stdout:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: dashboarding-route
spec:
  host: dashboarding-route.some-new-domain
  port:
    targetPort: 100
  tls:
    termination: passthrough
  to:
    kind: Service
    name: dashboarding

Solution2: use printf instead of echo

You could use printf instead of echo to preserve the yaml formatting, like so:

$: MYVARVALUE=some-new-domain
$: template=$(cat "file.yaml" | sed "s/domain/$MYVARVALUE/g")
$: printf '%s\n' "$template"

Which gives the following stdout:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: dashboarding-route
spec:
  host: dashboarding-route.some-new-domain
  port:
    targetPort: 100
  tls:
    termination: passthrough
  to:
    kind: Service
    name: dashboarding

Solution3: encode/decode stdout using base64

Another option to preserve formatting is to encode the data when storing/transmitting it, and then decode it when accessing/receiving it:

$: MYVARVALUE=some-new-domain
$: template=$(cat "file.yaml" | sed "s/domain/$MYVARVALUE/g" | base64 -w 0)
$: echo "$template" | base64 -d

Which also gives the following stdout:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: dashboarding-route
spec:
  host: dashboarding-route.some-new-domain
  port:
    targetPort: 100
  tls:
    termination: passthrough
  to:
    kind: Service
    name: dashboarding

This last solution is particularly useful for moving formatting-sensitive data such as ssh-keys or hash-values between machines; just be aware the this is not a substitute for encryption!

nyserq
  • 11
  • 3
  • 1
    `echo -e` is almost always a mistake. It's not portable (some versions just print "-e" in the output), and this case the only thing the `-e` option is going to do is to make `echo` try to interpret any backslashes in the data as escape sequences, possibly mangling the yaml as a result. `echo -n` is also unportable, and will give technically invalid output in this case. Just use plain `echo` with double-quotes around the variable. Also, in Solution2, you shouldn't put data in `printf`'s format string; use `printf '%s\n' "$template"` instead. – Gordon Davisson Aug 21 '23 at 02:50
  • 1
    That's good to know about the issues with `echo -e`, thanks for the heads-up :) – nyserq Aug 21 '23 at 13:27