How to increment the last number in a string; bash

  • A+

I have a string that looks something like /foo/bar/baz59_ 5stuff.thing

I would like to increase the last number (5 in the example) by one, if it's greater than another variable. A 9 would be increased to 10. Note that the last number could be multiple digits also; also that "stuff.thing" could be anything; other than a number; so it can't be hard coded.

The above example would result in /foo/bar/baz59_ 6stuff.thing

I've found multiple questions (and answers) that would extract the last number from the string, and obviously that could then be used in a comparison. The issue I'm having is how to ensure that when I do the replace, I only replace the last number (since obviously I can't just replace "5" for "6"). Can anyone make any suggestions?

awk/sed/bash/grep are all viable.


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.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: