Replace string after last dot in bash

In any POSIX shell:

var=123.444.888.235
new_var="${var%.*}.0"

${var%pattern} is an operator introduced by ksh in the 80s, standardized by POSIX for the standard sh language and now implemented by all shells that interpret that language, including bash.

${var%pattern} expands to the content of $var stripped of the shortest string that matches pattern off the end of it (or to the same as $var if that pattern doesn't match). So ${var%.*} (where .* is a pattern that means dot followed by any number of characters) expands to $var without the right-most . and what follows it. By contrast, ${var%%.*} where the longest string that matches the pattern is stripped would expand to $var without the left-most . and what follows it.


This should work.

echo 123.444.888.235 | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\.\)[0-9]*/\10/'

Note that the last field of sed substitution, \10, is the first matched pattern (\1), concatenated with a literal zero.


A few ways (these all assume that you want to change the last set of numbers in the string):

$ echo 123.444.888.235 | awk -F'.' -vOFS='.' '{$NF=0}1;'
123.444.888.0

Here, -F'.' tells awk to use . as the input field separator and -vOFS='.' to use it as the output field separator. Then, we simply set the last field ($NF) to 0 and print the line (1; is awk shorthand for "print the current line").

$ echo 123.444.888.235 | perl -pe 's/\d+$/0/'
123.444.888.0

The -p tells perl to print each input line after applying the script given by -e. The script itself is just a simple substitution operator which will replace one or more numbers at the end of the line with 0.

$ echo 123.444.888.235 | sed 's/[0-9]*$/0/'
123.444.888.0

The same idea in sed, using [0-9] instead of \d.


If your string is in a variable and you use a shell that supports here strings (such as bash or zsh for example), you can change the above to:

awk -F'.' -vOFS='.' '{$NF=0}1;' <<<$var
perl -pe 's/\d+$/0/' <<<$var
sed 's/[0-9]*$/0/' <<<$var