Perl Regex Command Line Issue

In Bash, ! is the "history expansion character", except when escaped with a backslash or single-quotes. (Double-quotes do not disable this; that is, history expansion is supported inside double-quotes. See Difference between single and double quotes in Bash)

So, just change your double-quotes to single-quotes:

echo 1.41.1 | perl -pe 's/(?![0-9]+\.[0-9]+\.)[0-9]$/2/g'

and voilà:

1.41.2

If you want to "increment" a number then you can't hard-code the new value but need to capture what is there and increment that

echo "1.41.1" | perl -pe's/[0-9]+\.[0-9]+\.\K([0-9]+)/$1+1/e'

Here /e modifier makes it so that the replacement side is evaluated as code, and we can +1 the captured number, what is then substituted. The \K drops previous matches so we don't need to put them back; see "Lookaround Assertions" in Extended Patterns in perlre.

The lookarounds are sometimes just the thing you want, but they increase the regex complexity (just by being there), can be tricky to get right, and hurt efficiency. They aren't needed here.

The strange output you get is because the double quotes used around the Perl program "invite" the shell to look at what's inside whereby it interprets the ! as history expansion and runs that, as explained in ruakh's post.


I'm guessing that this expression also might work:

([0-9.]+)\.([0-9]+)

Test

perl -e'
    my $name = "1.41.1";
    $name =~ s/([0-9.]+)\.([0-9]+)/$1\.2/;
    print "$name\n";
    '

Output

1.41.2

Please see the demo here.

Tags:

Regex

Bash

Perl