2

I have a perl program that takes the STDIN (piped from another bash command). The output from the bash command is quite large, about 200 lines. I want to take the entire input (multiple lines) and feed that to a one-liner perl script, but so far nothing i've tried has worked. Conversely, if I use the following perl (.pl file):

#!/usr/bin/perl
use strict;

my $regex = qr/{(?:\n|.)*}(?:\n)/p;

if ( <> =~ /$regex/g ) {
  print "${^MATCH}\n";
}

And execute my bash command like this:

<bash command> | perl -0777 try_m_1.pl

It works. But as a one-liner, it doesn't work with the same regex/bash command. The result of the print command is nothing. I've tried it like this:

<bash command> | perl -0777 -e '/{(?:\n|.)*}(?:\n)/pg && print "$^MATCH";'

and this:

<bash command> | perl -0777 -e '/{(?:\n|.)*}(?:\n)/g; print "$1\n";'

And a bunch of other things, too many to list them all. I'm new to perl and only want to use it to get regex output from the text. If there's something better than perl to do this (I understand from reading around that sed wouldn't work for this?) feel free to suggest.

Update: based on @zdim answer, I tried the following, which worked:

<bash command> |  perl -0777 -ne '/(\{(?:\n|.)*\}(?:\n))/s and print "$1\n"'

I guess my regex needed to be wrapped in () and the { curly braces needed to be escaped.

1
  • ${^MATCH} vs $^MATCH might be an issue. And you never capture anything for $1 to have a value... Plus your one liners need a -n... Commented Jun 7, 2019 at 1:33

1 Answer 1

3

A one-liner needs -n (or -p) to process input, so that files are opened, streams attached, and a loop set up. It still needs that even as the -0777 unsets the input record separator, so the file is read at once; see Why use the -p|-n in slurp mode in perl one liner?

That regex matches either a newline or any character other than a newline, and there is a modifier for that, /s, with which . matches newline as well. Then that need be inside curly braces, which you need to escape in newer Perls. The newline that follows doesn't need grouping.

So altogether you'd have

<bash command> | perl -0777 -ne'/(\{(.*)\}\n)/s and print "$1\n"'
Sign up to request clarification or add additional context in comments.

4 Comments

The regex and syntax wasn't quite correct (there is a single quote character ' after the /s that should not be there for example, but based on your suggestion @zdim, I tried ` perl -0777 -ne '/(\{(?:\n|.)*\}(?:\n))/s and print "$1\n"'` and that worked. Thanks.
@Nena Great, glad it worked and thank you for attribution. Thank you for notice about the typo! Fixed
Thank you for this explanation here. It was better than the duplicate in my closed question. :)
@LeoNatan Great, and thank you for saying this :). For reference here are then a couple more of related posts, a short one and one with more stuff.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.