user8557463
user8557463

Reputation:

increase value of returned value by 1 with makefile script

i've return number with the following format

v0.0.1

so in this case I need to change the number to

v0.0.2

if I got

v0.0.9

I want to change it to

v0.1.0

and so own...each time increase with one

what I've tried is the following

awk -F. '{$NF+=1; OFS="."; print $0}

which doesn't work(give the same value), what could be the problem ?

I use before VERSION=git describe --tags --abbrev=0 | awk -F. '{$NF+=1; OFS="."; print $0}'

which doesnt works...

update

When I try the code of james I got the value increased without the dots and without the v

enter image description here

Upvotes: 1

Views: 373

Answers (4)

James Brown
James Brown

Reputation: 37424

A play with the separators and record rebuilding:

$ echo 0.0.9 | 
awk '
BEGIN {
    FS="."                  # set the separators
    OFS=""
}
{
    sub(/^v/,"")            # remove the v
    $1=$1                   # rebuild record to remove periods
    $0=sprintf("%03d",$0+1) # zeropad the number after adding 1 to it
}
END {
    FS=""                   # reset the separators 
    OFS="."
    $0=$0                   # this to keep the value in $0
    $1=$1                   # rebuild to get the periods back
    print "v" $0            # output
}'
v0.1.0

Seemed to work with 9.9.9 -> 1.0.0.0.

Upvotes: 3

kyodev
kyodev

Reputation: 583

pure bash, on @ghoti solution

#!/bin/bash

increase_version(){
    local string display c

    string=$((10#${1//[^0-9]}+1))
    string=$(printf "%03d\n" "$string" )
    for (( c=0; c < ${#string}; c++ )); do
        display+="${string:$c:1}."
    done
    echo "v${display::-1}"
}

echo -n "v0.0.1  ->  " ; increase_version "v0.0.1"
echo -n "v0.0.9  ->  " ; increase_version "v0.0.9"

echo -e "\nbash $BASH_VERSION"

output

v0.0.1  ->  v0.0.2
v0.0.9  ->  v0.1.0

bash 4.4.18(1)-release

bench

loop with 10000 iterations:

  • bash only: 8972 ms
  • with sed: 16020 ms
  • with awk: 24830 ms (script @JamesBrown)

the execution time is not the only standard of quality, I publish it for information

Upvotes: 1

ghoti
ghoti

Reputation: 46876

Well, in a bash function, what about this?

$ function incv { printf "%03d\n" $((10#${1//[^0-9]/}+1)) | sed -E 's/(.)(.)(.)/v\1.\2.\3/'; }
$ incv v0.0.9
v0.1.0
$ incv v0.1.5
v0.1.6

The idea here is:

  1. we remove non-digits and treat the number like a normal base 10 number,
  2. we increment the number, and
  3. we print the number as a zero-padded 3 digit number, with reformatting by sed.

We could do the sed part in bash alone, but it would be more work....

I think the only weird part of this is the 10#. Its purpose is to ensure that the number is interpreted as base 10, since a leading 0 might otherwise cause bash to consider the number to be octal. Which wouldn't work for v0.0.9. :)

Upvotes: 2

kabanus
kabanus

Reputation: 25980

The minor problem is OFS needs to be set before you increase the column. The worse problem is you don't handle the case for 9 (0.0.9->0.1.0):

#!/bin/bash
awk -F. '{OFS="."; 
    printf("v");
    for(i=NF; i>0;i--) {
        $i++;
        if ($i<10) break;
        if(i>1) $i=0;
    }
}1'

This can be a one liner, I just put it in a script for readability. You would use it:

echo 9.9.9 | myscript.bash

Another problem is overflow, handled by the if(i>1). Note the input cannot contain a v. If you have in bash VERSION=v1.2.3, you can easily get the relevant substring with ${VERSION:1}.

Upvotes: 2

Related Questions