1

I have a file that includes this line:

  master_green_cloud_init_version = "v1.16/"

My bash script will have a parameter like userdata_version=v2.21.

How can I use sed to replace anything between the "" (i.e. "v1.16/") with $userdata_version?

I cannot hard code v1.16 as it keeps on changing.

Greenonline
  • 1,851
  • 7
  • 17
  • 23
Robert Chen
  • 47
  • 1
  • 5

2 Answers2

3

To use sed, for the scenario that you describe, with an input file like this:

master_green_cloud_init_version = "v1.16/"
master_blue_cloud_init_version = "v1.16/"

This script*

#!/bin/sh

userdata_version=v2.21 sed -i -e "/master_green_cloud_init_version/s/".*"/"${userdata_version}"/" input.txt

results in

$ more input.txt
master_green_cloud_init_version = "v2.21"
master_blue_cloud_init_version = "v1.16/"
$

Note that you need double quotes for the sed expression, in order to use the shell variable, see this answer to Shell variables in sed script.

Then you also need to escape the double quotes that you are searching for, using \". You will need to do this twice, once for the starting double quote and once for the end.

The -i works on the input file rather than just outputting the result to stdout.


Note: If, for some reason, you want to keep the forward slash at the end of the version string, then use an escaped forward slash (\/), like so:

#!/bin/sh

userdata_version=v2.21 sed -e "/master_green_cloud_init_version/s/".*/"/"${userdata_version}/"/" input.txt

which, for the same input file, gives

master_green_cloud_init_version = "v2.21/"
master_blue_cloud_init_version = "v1.16/"

* From How to use sed to find and replace text in files in Linux / Unix shell:

How to use sed to match word and perform find and replace

In this example only find word ‘love’ and replace it with ‘sick’ if line content a specific string such as FOO:

sed -i -e '/FOO/s/love/sick/' input.txt 

See also How can I replace a string in a file(s)?

Greenonline
  • 1,851
  • 7
  • 17
  • 23
  • sorry, as the replace string is a folder, still needs a backslash, userdata_version=v2.21/, then your solution does not work with backslack in the string to be replaced. please help? – Robert Chen Aug 30 '21 at 16:39
  • thanks, it works in sh or some bash as well, but in my environment (jenkins pipeline kubernetes pod, it does not work). it is replace as the value of $userdata_version, and "master_green_cloud_init_version =" was removed. – Robert Chen Aug 30 '21 at 19:37
  • Ah, you didn't specify that in your question, you said "My bash script will have..." and you tagged the question with the bash tag. I think that is a different question altogether, like "Why doesn't sed work as expected in 'jenkins pipeline kubernetes pod'?" – Greenonline Aug 31 '21 at 02:55
  • I think that this answer to Jenkins: Pipeline sh bad substitution error will help you. If it does, I'll update my answer. – Greenonline Sep 01 '21 at 03:32
1

Assuming that the file is a configuration file written in TOML format, then you may use the tomlq parser to change the value, given the shell variable userdata_version with a new value:

tomlq -t --arg newversion "$userdata_version" \
        '.master_green_cloud_init_version |= $newversion' file.toml

This would update the value of the top-level key master_green_cloud_init_version to the value assigned with --arg to the internal variable $newversion. The modified document is written to standard output (you may do in-place editing with the --in-place option).

Testing:

$ cat file.toml
  master_green_cloud_init_version = "v1.16/"
$ userdata_version=v2.21
$ tomlq -t --arg newversion "$userdata_version" '.master_green_cloud_init_version |= $newversion' file.toml
master_green_cloud_init_version = "v2.21"
Kusalananda
  • 333,661