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

I am trying to print multiple regex matches using Perl one liner but it does not work. Here is the data from where I am trying to extract info. name=abc dep=HR type=permanent age=35 name=xyz dep=Sales type=contract age=31 If I try to only print name it works fine.
perl -nle ' print $1 if /name=(\w+)/' filename
But I need information from other fields too. I tried the following command but there is no output
perl -nle ' print $1 $2 if /name=(\w+).*age=(\d+)/' filename
Also tried.
perl -nle ' print $1 if /name=(\w+)/ && print $2 if /age=(\d+)/' filen +ame
Help is appreciated.

Replies are listed 'Best First'.
Re: One Liner, print multiple regex matches
by toolic (Bishop) on Nov 16, 2012 at 21:45 UTC
    Add quotes around $1 and $2:
    perl -nle ' print "$1 $2" if /name=(\w+).*age=(\d+)/' filename

    warnings can also be used with one-liners to help you debug:

    perl -nlew ' print $1 $2 if /name=(\w+).*age=(\d+)/' filename Can't open print $1 $2 if /name=(\w+).*age=(\d+)/: No such file or di +rectory.

    Please update your post to add "code" tags around your input file data.

      Thank's It worked!

      I simply added the quotes and its showing data for both regex matches.

      Working code:
      perl -nle ' print "$1$2" if /name=(\w+).*age=(\d+)/' filename
Re: One Liner, print multiple regex matches
by kennethk (Abbot) on Nov 16, 2012 at 21:43 UTC
    In both those cases, you've got syntax errors. You could modify the second one to use two look-aheads (see Looking ahead and looking behind in perlretut) to grab the fields:

    perl -nle ' print "$1$2" if /(?=name=(\w+))(?=age=(\d+))/' filename

    Note how your omission of quotes or a comma from your second case means that $1 is being treated at a filehandle.

    Your third version fails because you are only allowed one if per statement (see Compound Statements). You could make this work using && and || like:

    perl -nle ' /name=(\w+)/ && print($1) || /age=(\d+)/ && print($1) ' filename

    or, use two different statements to make it even easier:

    perl -nle 'print $1 if /name=(\w+)/; print $1 if /age=(\d+)/' filename

    Note that you are using two different regular expressions, so each one would set the $1 buffer if it matches.

    As a last comment, assuming you are running a reasonably recent version of perl, your output might be easier to deal with if you use -E in place of -e and swap your prints to says (see perlrun).

    Oh, and please wrap input data in <code> tags, as white space is mangled on display if you don't.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: One Liner, print multiple regex matches
by Kenosis (Priest) on Nov 16, 2012 at 22:51 UTC

    Another option with your data is to capture the text on either side of the equals sign:

    perl -nle "print qq{$1 => $2} while /(\S+)=(\S+)/g" data.txt

    Output:

    name => abc dep => HR type => permanent age => 35 name => xyz dep => Sales type => contract age => 31
      Thanks Kenosis. :)
        You're most welcome, cipher!