Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I match across newlines in a perl regex?

Tags:

regex

shell

perl

I'm trying to work out how to match across newlines with perl (from the shell). following:

(echo a b c d e; echo f g h i j; echo l m n o p) | perl -pe 's/(c.*)/[$1]/'

I get this:

a b [c d e]
f g h i j
l m n o p

Which is what I expect. But when I place an /s at the end of my regex, I get this:

a b [c d e
]f g h i j
l m n o p

What I expect and want it to print is this:

a b [c d e
f g h i j
l m n o p
]

Is the problem with my regex somehow, or my perl invocation flags?

like image 481
Sophistifunk Avatar asked Dec 06 '22 10:12

Sophistifunk


2 Answers

-p loops over input line-by-line, where "lines" are separated by $/, the input record separator, which is a newline by default. If you want to slurp all of STDIN into $_ for matching, use -0777.

$ echo "a b c d e\nf g h i j\nl m n o p" | perl -pe 's/(c.*)/[$1]/s'
a b [c d e
]f g h i j
l m n o p
$ echo "a b c d e\nf g h i j\nl m n o p" | perl -0777pe 's/(c.*)/[$1]/s'
a b [c d e
f g h i j
l m n o p
]

See Command Switches in perlrun for information on both those flags. -l (dash-ell) will also be useful.

like image 85
Josh Y. Avatar answered Dec 23 '22 18:12

Josh Y.


The problem is that your one-liner works one line at a time, your regex is fine:

use strict;
use warnings;
use 5.014;

my $s = qq|a b c d e
f g h i j
l m n o p|;

$s =~ s/(c.*)/[$1]/s;

say $s;
like image 27
Tudor Constantin Avatar answered Dec 23 '22 17:12

Tudor Constantin