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