bliako has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I can not understand why this works:

my $x = <<'EOX'; A { B 123 C xyz } EOX $x =~ s/A\s*\{.+?\}//s; print "x='$x'\n"; # empty

but this does not (linux terminal):

perl -pe 's/A\s*\{.+?\}//s' <<'EOX' A { B 123 C xyz } EOX # prints exactly what the input is

I have checked if there are mistaken shell interpolations to the oneliner script, but there are not, I think:

x='s/A\s*\{.+?\}//s' echo $x # s/A\s*\{.+?\}//s

Edit: the same problem if the oneliner operates on a file:

cat > infile<<'EOX' A { B 123 C xyz } EOX perl -pe 's/A\s*\{.+?\}//s' infile # or perl -i -pe 's/A\s*\{.+?\}//s' infile

Replies are listed 'Best First'.
Re: Why dot does not match newline in oneliner but it does in script, with /s modifier?
by hippo (Archbishop) on Oct 24, 2025 at 14:50 UTC

    You are running perl -p which by default processes each line in isolation, therefore your regex will never match because you don't have a line with both an opening and closing brace on it, for example.

    You could change the line-ender to null to switch this behaviour off:

    $ perl -lp0e 's/A\s*\{.+?\}//s' <<EOX > A { > B 123 > C xyz > } > EOX

    This gives the empty output as you initially expected.

    Update: See the discussion in the follow-up question Oneliner replace in-place adds extra spaces at the end of the file particularly in regards to the use of -l and how the order of these options is important.


    🦛

      indeed it does work, thank you. I came from sed who has difficulties handling multi-line chunks but got beaten by the defaults.