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

folks, I have the following data file :
(CSW - Q1) OMIPMS55:NTTCSWQ1:MQSI.3PL846 OMIPMS55:NTTCSWQ1:MQSI.STATUS OMIPMS55:NTTCSWQ1:MQSI.3PLXDOCK.STATE (CSW - Q2) OMIPMS55:NTTCSWQ2:MQSI.3PL846 OMIPMS55:NTTCSWQ2:MQSI.3PL944 (CSW - Q3) OMIPMS55:NTTCSWQ3:MQSI.3PL846
I am trying to read that data file and read the lines which don't contains (....) , however inside the loop I don't want to loop for every single line. in other words ,, forexample how would I read what is between (CSW - Q1) and (CSW - Q2) only without printing (CSW - Q1) and (CSW - Q2) , right now I have the following :
open (INPUT, "data") || die "couldn't open the file!"; open (OUTPUT, ">result.out") || die "couldn't open the file!"; foreach $line (<INPUT>) { chomp $line; if ( $line !~ /^\[.*\]/ ) { ($server, $queuem, $queue)= split(/:/, $line); system qq(telnet -host $server -user mqadmin -passwd >> out); } } close(OUTPUT); close(INPUT);
this will print all lines and it will loop foreach line , I want it to treat what is between (***) till the next (**) as one group and not go through the loop for every time . If I am not making sense please let me know I will try to explaing better ,, thanks in advance .

Replies are listed 'Best First'.
Re: matching some lines
by GrandFather (Saint) on Nov 12, 2007 at 22:14 UTC

    You can set the input record separator ($/) to ) and input your data a block at a time. Resetting the separator inside the chunk reading loop reuses the same trick to parse the lines. Consider:

    use strict; use warnings; my $data = <<DATA; (CSW - Q1) OMIPMS55:NTTCSWQ1:MQSI.3PL846 OMIPMS55:NTTCSWQ1:MQSI.STATUS OMIPMS55:NTTCSWQ1:MQSI.3PLXDOCK.STATE (CSW - Q2) OMIPMS55:NTTCSWQ2:MQSI.3PL846 OMIPMS55:NTTCSWQ2:MQSI.3PL944 (CSW - Q3) OMIPMS55:NTTCSWQ3:MQSI.3PL846 DATA local $/ = ')'; open IN, '<', \$data; while (defined (my $chunk = <IN>)) { chomp $chunk; local $/ = "\n"; open LINES, '<', \$chunk; my @lines = <LINES>; close LINES; pop @lines if $lines[-1] =~ '\('; print @lines; } close IN;

    Prints:

    OMIPMS55:NTTCSWQ1:MQSI.3PL846 OMIPMS55:NTTCSWQ1:MQSI.STATUS OMIPMS55:NTTCSWQ1:MQSI.3PLXDOCK.STATE OMIPMS55:NTTCSWQ2:MQSI.3PL846 OMIPMS55:NTTCSWQ2:MQSI.3PL944 OMIPMS55:NTTCSWQ3:MQSI.3PL846

    Perl is environmentally friendly - it saves trees
Re: matching some lines
by CountZero (Bishop) on Nov 12, 2007 at 21:40 UTC
    Perhaps something like this?
    $whole_file = join ('', <DATA>); @parts = split /\(.*?\)/, $whole_file; foreach (@parts) { print if $_; } __DATA__ (CSW - Q1) OMIPMS55:NTTCSWQ1:MQSI.3PL846 OMIPMS55:NTTCSWQ1:MQSI.STATUS OMIPMS55:NTTCSWQ1:MQSI.3PLXDOCK.STATE (CSW - Q2) OMIPMS55:NTTCSWQ2:MQSI.3PL846 OMIPMS55:NTTCSWQ2:MQSI.3PL944 (CSW - Q3) OMIPMS55:NTTCSWQ3:MQSI.3PL846

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James