This works:
echo "aaa\n\n\nbbb" | perl -pe "s/\\n/z/gm"
aaazzzbbbz
This doesn't match anything:
echo "aaa\n\n\nbbb" | perl -pe "s/\\n\\n/z/gm"
aaa
bbb
How do I fix, so the regex matches two consecutive newlines?
CodePudding user response:
You are applying substitution to only one line at a time, and one line will never have two newlines. Apply the substitution to the entire file instead:
perl -0777 -pe 's/\\n\\n/z/g'
CodePudding user response:
A linefeed is matched by \n
echo "a\n\n\b" | perl -pe's/\n/z/'
This prints azzb
, and without the following newline, so with the next prompt on the same line. Note that the program is fed one line at a time so there is no need for /g
modifier. (And which is why \n\n
doesn't match.) That /m
modifier is then unrelated to this example.†
I don't know in what form this is used but I'd imagine not with echo
feeding the input? Then better test it with input in a file, or in a multi-line string (in which case /g
may be needed).
An example
use warnings;
use strict;
use feature 'say';
# Test with multiline string
my $ml_str = "a\n\nb\n";
$ml_str =~ s/\n/z/g; #--> azzbz (no newline at the end)
print $ml_str;
say ''; # to terminate the line above
# Or to replace two consecutive newlines (everywhere)
$ml_str = "a\n\nb\n"; # restore the example string
$ml_str =~ s/\n\n/z/g; #--> azb\n
print $ml_str;
# To replace the consecutive newlines in a file read it into a string
my $file = join '', <DATA>; # lines of data after __DATA__
$file =~ s/\n\n/z/g;
print $file;
__DATA__
one
two
last
This prints
azzbz azb one twoz last
Another way to match a newline is with the modifier /s
, with which the .
pattern matches linefeeds as well. So s/./z/sg
also replaces all linefeeds, but then so it does with other characters as well.
See perlrebackslash and search for newline
.
† The /m
modifier makes ^
and $
also match beginning and end of lines inside a multi-line string. Then
$multiline_string =~ s/$/z/mg;
will replace newlines inside the string. However, this example bears some complexities since some of the newlines stay.