Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Grepping with Perl: How to stop after first match?

by BrowserUk (Patriarch)
on Dec 06, 2007 at 10:25 UTC ( [id://655352]=note: print w/replies, xml ) Need Help??


in reply to Grepping with Perl: How to stop after first match?

People seem to have missed that you are looking for "2-line strings". Reading and matching one line at a time won't succeed.

You need to maintain a rolling two-line buffer to do this.

...## get $fh from somewhere (eg.open) my $last = ''; while( <$fh> ) { ( $last . $_ ) =~ m[cpuinfo\nvendor_id\s+:\s(.*?)\n] and print qq[CPU:$1] and last; $last = $_; } ...

Or as a (longish) one-liner

perl -ne"($last.$_)=~m[cpuinfo\nvendor_id\s+:\s(.*?)\n]&&print qq[CPU: +$1]&&exit;$last=$_" yourfile

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: Grepping with Perl: How to stop after first match?
by paulnovl (Novice) on Dec 07, 2007 at 11:22 UTC
    Thanks for the suggestion. I think that comes close to what I'm trying to achieve. Problem is that the "exit" doesn't allow me to continue with further grepping of the input stream.

    Here's a more complete snippet of the shell script that I'm using, showing that I'm just trying to use Perl to grep the incoming data stream (in paragraph mode).
    #! /bin/sh ## other stuff happens here, but snipped for clarity scdir=/var/log find $scdir -type f -name "nts_*.bz2" | # find interesting files in + $scdir perl -wnl -e '7 > -M and print;' | # ignore old files xargs bzcat -k | # unpack contents to STDOUT perl -wn00 -e ' # paragraph mode m[kernel\.hostname\s.\s(.*?)\n] and print "Hostname:\t$1\n"; # +grep for hostname m[\/bin\/date\n(.*?)\n] and print "Generated:\t$1\n"; # grep fo +r date ## I grep for other stuff here, but snipped for clarity m[Settings.for\s(.*?):\n] and print "Interface:\t$1\n"; # g +rep for eth interfaces m[Speed:\s(.*?)Mb\/s] and # grep for interface spee +d print "\ -speed:\t$1Mb\/s\n" ; m[Duplex:\s(.*?)\n] and # grep for interface duplex print "\ -duplex:\t$1\n" ; m[Auto-negotiation:\s(.*?)\n] and # grep for interface +autoneg print "\ -autoneg:\t$1\n" ; m[cpuinfo\nvendor_id\s+:\s(.*?)\n] and # grep for cpu id print "CPU:\t\t$1\n" ; ' exit $!

    The output is something like the following:
    Generated: Tue Dec 4 12:12:01 GMT 2007 Hostname: lnx0010 CPU: IBM/S390 CPU: IBM/S390 Interface: hsi0 -speed: 100Mb/s -duplex: Full -autoneg: on Interface: hsi1 -speed: 100Mb/s -duplex: Full -autoneg: on Interface: sit0 -speed: 100Mb/s -duplex: Full -autoneg: on CPU: IBM/S390 Generated: Mon Dec 3 12:34:19 GMT 2007 Hostname: ptsuse3 CPU: GenuineIntel Interface: eth0 -speed: 100Mb/s -duplex: Full -autoneg: on Interface: eth1 -speed: 100Mb/s -duplex: Full -autoneg: on Generated: Mon Jun 18 15:33:40 BST 2007 Hostname: icore-71 CPU: GenuineIntel CPU: GenuineIntel Interface: eth0 -speed: 100Mb/s -duplex: Half -autoneg: on

    You'll notice that there are several "CPU:" lines -- and that's because there are several occurences of the following 2-line string in the input stream:
    # /proc/cpuinfo vendor_id : IBM/S390

    I'm wanting to quit after matching the first occurence of that string, but to continue with my other "grep" statements.

    I'm new to Perl, so am open to criticism of my general approach to this problem.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://655352]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2024-04-20 04:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found