How to increment the last number in a string; bash
Updated Answer
Thanks to @EdMorton for pointing out the further requirement of the number exceeding a threshold. That can be done like this:
perl -spe 's/(\d+)(?!.*\d+)/$1>$thresh? $1+1 : $1/e' <<< "abc123_456.txt" -- -thresh=500
Original Answer
You can evaluate/calculate a replacement with /e
in Perl regexes. Here I just add 1 to the captured string of digits but you can do more complicated stuff:
perl -pe 's/(\d+)(?!.*\d+)/$1+1/e' <<< "abc123_456.txt"
abc123_457.txt
The (?!.*\d+)
is (hopefully) a negative look-ahead for any more digits.
The $1
represents any sequence of digits captured in the capture group (\d+)
.
Note that this would need modification to handle decimal numbers, negative numbers and scientific notation - but that is possible.
Using bash regular expression matching:
$ f="/foo/bar/baz59_ 99stuff.thing"
$ [[ $f =~ ([0-9]+)([^0-9]+)$ ]]
OK, what do we have now?
$ declare -p BASH_REMATCH
declare -ar BASH_REMATCH=([0]="99stuff.thing" [1]="99" [2]="stuff.thing")
So we can construct the new filename
if [[ $f =~ ([0-9]+)([^0-9]+)$ ]]; then
prefix=${f%${BASH_REMATCH[0]}} # remove "99stuff.thing" from $f
number=$(( 10#${BASH_REMATCH[1]} + 1 )) # use "10#" to force base10
new=${prefix}${number}${BASH_REMATCH[2]}
echo $new
fi
# => /foo/bar/baz59_ 100stuff.thing
With GNU awk for the 3rd arg to match():
$ awk -v t=3 'match($0,/(.*)([0-9]+)([^0-9]*)$/,a) && a[2]>t{a[2]++; $0=a[1] a[2] a[3]} 1' file
/foo/bar/baz59_ 6stuff.thing
Just set t
to whatever your threshold value is for incrementing, e.g.:
$ awk -v t=7 'match($0,/(.*)([0-9]+)([^0-9]*)$/,a) && a[2]>t{a[2]++; $0=a[1] a[2] a[3]} 1' file
/foo/bar/baz59_ 5stuff.thing