anXler
anXler

Reputation: 317

Update file content using a bash script

I have a docker-compose file, in which I have a docker images with its versioning tag, example myrepo.com/myimage:1.0.1.0. I want to write a bash script that receives the version number as a parameter and updates the version tag of the relevant image.

Currently I am using the below command to replace the version tag with the help of grep and sed, but I believe there should be a more efficient way for this. Any suggestions?

sedval='1.1.1.1'  # <-- new value

imageval=$(grep -i 'image: myrepo.com/myimage:' docker-compose.yml | cut -d ':' -f2,3)
imagename=$(grep -i 'image: myrepo.com/myimage:' docker-compose.yml | cut -d ':' -f2)
imageversion=$(grep -i 'image: myrepo.com/myimage:' docker-compose.yml | cut -d ':' -f3)
sed -i -e "s+$imageval+$imagename:$sedval+g" docker-compose.yml

Upvotes: 0

Views: 1449

Answers (2)

b0gusb
b0gusb

Reputation: 4701

docker-compose supports variable substitution. You could do the following:

 version: "3"
   services:
      myrepo:
       image: myrepo.com/myimage:${VERSION}

docker-compose looks for the VERSION environment variable and substitutes its value in the file. Run with:

export VERSION=1.1.1.1; docker-compose up

Upvotes: 2

tripleee
tripleee

Reputation: 189297

Manipulating YAML with line-oriented regex tools is generally not advisable. You should probably switch to a YAML-aware tool like yq for this.

There doesn't seem to be a reason you extract imageversion; you assign this variable, but never use it. In fact, if you forgo the requirement to match case-insensitively, all you really need is

sed -i "s+\\(image: myrepo\\.com/myimage:\\)[.0-9]*+\\1$1+" docker-compose.yml

assuming (like you say in your question) the new version number is in $1, which is the first command-line argument to your script.

I don't think Docker allows you to use upper case; and if it does, you can replace i with [Ii], m with [Mm], etc. Notice also how the literal dot needs to be backslash-escaped, strictly speaking.

Generally speaking, you can often replace grep 'x' | sed 'y' with sed '/x/y'; see also useless use of grep. Also, the repeated grep could easily be refacored into a single grep with something like

imageval=$(grep -i 'image: myrepo.com/myimage:' docker-compose.yml)
imagever=${imageval##*:}
imagename=${imageval%:$imagever}

where the shell parameter substitutions are both simpler and more elegant as well as more efficient than repeatedly spawning cut in a separate process for this very simple string extraction task.

Upvotes: 1

Related Questions