user6329667
user6329667

Reputation: 517

Update version number in property file using bash

I am new in bash scripting and I need help with awk. So the thing is that I have a property file with version inside and I want to update it.

version=1.1.1.0

and I use awk to do that

file="version.properties"

awk -F'["]' -v OFS='"' '/version=/{
    split($4,a,".");
    $4=a[1]"."a[2]"."a[3]"."a[4]+1
    }
;1' $file > newFile && mv newFile $file

but I am getting strange result version="1.1.1.0""...1

Could someone help me please with this.

Upvotes: 2

Views: 1700

Answers (3)

cxw
cxw

Reputation: 17051

You mentioned in your comment you want to update the file in place. You can do that in a one-liner with perl:

perl -pe '/^version=/ and s/(\d+\.\d+\.\d+\.)(\d+)/$1 . ($2+1)/e' -i version.properties

Explanation

-e is followed by a script to run. With -p and -i, the effect is to run that script on each line, and modify the file in place if the script changes anything.

The script itself, broken down for explanation, is:

/^version=/ and              # Do the following on lines starting with `version=`
s/                           # Make a replacement on those lines
    (\d+\.\d+\.\d+\.)(\d+)/  # Match x.y.z.w, and set $1 = `x.y.z.` and $2 = `w`
    $1 . ($2+1)/             # Replace x.y.z.w with a copy of $1, followed by w+1
    e                        # This tells Perl the replacement is Perl code rather
                             # than a text string.

Example run

$ cat foo.txt
version=1.1.1.2
$ perl -pe '/^version=/ and s/(\d+\.\d+\.\d+\.)(\d+)/$1 . ($2+1)/e' -i foo.txt
$ cat foo.txt
version=1.1.1.3

Upvotes: 4

cxw
cxw

Reputation: 17051

This is not the best way, but here's one fix.

Test case

I am assuming the input file has at least one line that is exactly version=1.1.1.0.

$ awk -F'["]' -v OFS='"' '/version=/{
>     split($4,a,".");
>     $4=a[1]"."a[2]"."a[3]"."a[4]+1
>     }
> ;1'    <<<'version=1.1.1.0'

Output:

version=1.1.1.0"""...1

The """ is because you are assigning to field 4 ($4). When you do that, awk adds field separators (OFS) between fields 1 and 2, 2 and 3, and 3 and 4. Three OFS => """, in your example.

Minimal change

$ awk -F'["]' -v OFS='"' '/version=/{
    split($1,a,".");
    $1=a[1]"."a[2]"."a[3]"."a[4]+1; 
    print
}
'        <<<'version=1.1.1.0'
version=1.1.1.1

Two changes:

  • Change $4 to $1

    • Since the input field separator (-F) is ["], $4 is whatever would be after the third " (if there were any in the input). Therefore, split($4, ...) splits an empty field. The contents of the line, before the first " (if any), are in $1.
  • print at the end instead of ;1

    • The 1 after the closing curly brace is the next condition, and there is no action specified. The default action is to print the current line, as modified, so the 1 triggers printing. Instead, just print within your action when you are done processing. That way your action is self-contained. (Of course, if you needed to do other processing, you might want to print later, after that processing.)

Upvotes: 2

hek2mgl
hek2mgl

Reputation: 158100

You can use the = as the delimiter, like this:

awk -F= -v v=1.0.1 '$1=="version"{printf "version=\"%s\"\n", v}' file.properties

Upvotes: 1

Related Questions