http://qs321.pair.com?node_id=656720

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

Hello Monks , I have the following input file which I try to capture data from :
end sleep 10 dis qremote(MQSI.3PL846)RNAMERQMNAME1 : dis qremote(MQSI.3PL846) RNAME + RQMNAME AMQ8409: Display Queue details.QUEUE(MQSI.3PL846)TYPE(QREMOTE)RQMNAME( +MSTBKRQ1)RNAME(MQSI.3PL846) end2 : end Starting MQSC for queue manager NTTCSWQ1. AMQ8409: Display Queue details.QUEUE(MQSI.3PL944)TYPE(QREMOTE)RQMNAME( +MSTBKRQ1)RNAME(MQSI.3PL944) exit 5724-H72 (C) Copyright IBM Corp. 1994, 2004. ALL RIGHTS RESERVED. 1 : dis qremote(MQSI.ADM850) RNAME RQMNAME AMQ8409: Display Queue details. QUEUE(MQSI.ADM850) TYPE(QREMOTE) RQMNAME(MSTBKRQ1) RNAME(MQSI.ADM850) 2 : end end sleep 10 exit AMQ8409: Display Queue details. QUEUE(MQSI.ADMAPTR) TYPE(QREMOTE) RQMNAME(MSTBKRQ1) RNAME(MQSI.ADMAPTR) 2 : end One MQSC command read. No commands have a syntax error. All valid MQSC commands were processed.
what I am trying to capture is the QUEUE , RNAME and RQNAME values everytime I see the code AMQ8409, but as you can see the values which I am looking for can be on one line or somtimes written in 2 lines, so I did the following :
foreach my $line (<INPUT>) { my $match_queue = qr{ QUEUE # literal word 'QUEUE' \( # literal open paren (.*?) # non-greedy capture of >=0 \) # literal close paren }xms; my $match_rname = qr{ RNAME # literal word 'RNAME' \( # literal open paren (.*?) # non-greedy capture of >=0 \) # literal close paren }xms; my $match_qmname = qr{ RQMNAME # literal word 'RQMNAME' \( # literal open paren (.*?) # non-greedy capture of >=0 \) # literal close paren }xms; if ( $line =~ /AMQ8409/ ) { #if ( $line =~ /AMQ8409/ || $line =~ /\s\s\sQUEUE\(/ || $line =~ /RNAM +E/ ) { my ($queue) = ($line =~ $match_queue); my ($rname) = ($line =~ $match_rname); my ($qmname) = ($line =~ $match_qmname);
This is capturing the value for only the first 2 times the code AMQ8409 appears , I am not able to caputre the other 2 because the way the input file is written . Can someone advice of a way to do that ? thanks much

Replies are listed 'Best First'.
Re: capturing from Input file
by BrowserUk (Patriarch) on Dec 12, 2007 at 23:19 UTC

    #! perl -slw use strict; while( <DATA> ) { next unless m[^AMQ8409]; ## Skip to the starting condition ## Accumulate lines until we match $_ .= <DATA> until m[ QUEUE \( ( [^)]+ ) \) \s* TYPE \( [^)]+ \) \s* RQMNAME \( ( [^)]+ ) \) \s* RNAME \( ( [^)]+ ) \) ]xm; ## do something with the captured data print( "'$1'$2'$3'" ) if defined $1; } __DATA__

    Given the posted data as input produces:

    c:\test>junk 'MQSI.3PL846'MSTBKRQ1'MQSI.3PL846' 'MQSI.3PL944'MSTBKRQ1'MQSI.3PL944' 'MQSI.ADM850'MSTBKRQ1'MQSI.ADM850' 'MQSI.ADMAPTR'MSTBKRQ1'MQSI.ADMAPTR'

    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.
Re: capturing from Input file
by johngg (Canon) on Dec 12, 2007 at 22:59 UTC
    As long as your input file is not too large you could slurp the whole file into one string and do global matches against it. Use the s flag in the regex to allow the dot metacharacter to match newlines.

    use strict; use warnings; open my $inputFH, q{<}, \ <<'END_OF_FILE' or die qq{open: $!\n}; end sleep 10 dis qremote(MQSI.3PL846)RNAMERQMNAME1 : dis qremote(MQSI.3PL846) RNAME + RQMNAME AMQ8409: Display Queue details.QUEUE(MQSI.3PL846)TYPE(QREMOTE)RQMNAME( +MSTBKRQ1)RNAME(MQSI.3PL846) end2 : end Starting MQSC for queue manager NTTCSWQ1. AMQ8409: Display Queue details.QUEUE(MQSI.3PL944)TYPE(QREMOTE)RQMNAME( +MSTBKRQ1)RNAME(MQSI.3PL944) exit 5724-H72 (C) Copyright IBM Corp. 1994, 2004. ALL RIGHTS RESERVED. 1 : dis qremote(MQSI.ADM850) RNAME RQMNAME AMQ8409: Display Queue details. QUEUE(MQSI.ADM850) TYPE(QREMOTE) RQMNAME(MSTBKRQ1) RNAME(MQSI.ADM850) 2 : end end sleep 10 exit AMQ8409: Display Queue details. QUEUE(MQSI.ADMAPTR) TYPE(QREMOTE) RQMNAME(MSTBKRQ1) RNAME(MQSI.ADMAPTR) 2 : end One MQSC command read. No commands have a syntax error. All valid MQSC commands were processed. END_OF_FILE my $lines = do { local $/; <$inputFH>; }; close $inputFH or die qq{close: $!\n}; my $rxExtract = qr {(?xs) AMQ8409 .*? QUEUE\(([^)]+)\) .*? RQMNAME\(([^)]+)\) .*? RNAME\(([^)]+)\) }; while ( $lines =~ m{$rxExtract}g ) { print qq{QUEUE: $1, RQMNAME: $2, RNAME: $3\n}; }

    The output.

    QUEUE: MQSI.3PL846, RQMNAME: MSTBKRQ1, RNAME: MQSI.3PL846 QUEUE: MQSI.3PL944, RQMNAME: MSTBKRQ1, RNAME: MQSI.3PL944 QUEUE: MQSI.ADM850, RQMNAME: MSTBKRQ1, RNAME: MQSI.ADM850 QUEUE: MQSI.ADMAPTR, RQMNAME: MSTBKRQ1, RNAME: MQSI.ADMAPTR

    I hope this is helpful.

    Cheers,

    JohnGG

Re: capturing from Input file
by pc88mxer (Vicar) on Dec 12, 2007 at 23:02 UTC
    It looks like the output is block oriented. Each block begins with /^AMQ8409/ and ends with end.

    Can you read all of the output in at once? If so, you can use the /g regular expression modifier like this:

    while ($output =~ m/...re.../sg) { ... process block ... }
    The regular expression could be something like:
    $re = qr{AMQ8409.*?QUEUE\((.*?)\).*?RQMNAME\((.*?)\).*?RNAME\((.*?)\). +*?end};
    Note, this assumes that all blocks will have QUEUE, RQMNAME and RNAME in them and in that order. A more general approach is to break it up into blocks and then parse out anything that looks like IDENT(...) into a hash:
    while ($output =~ m/(AMQ8409.*?end)/gs) { my $block = $1; my %hash; while ($block =~ m{(\w+)\((.*?)\)}g) { $hash{$1} = $2; } # process block # use $hash{QUEUE}, $hash{RQMNAME}, $hash{RNAME}, etc. }
    Finally, for a line-oriented processing solution, try something like:
    my %hash; while (<>) { if (m/^AMQ8904/) { # start of block found %hash = (); } elsif (m/end/) { # end of block found ... process block ... } else { $hash{QUEUE} = $1 if m/QUEUE\((.*)\)/; $hash{RNAME} = $1 if m/RNAME\((.*)\)/; # ... add more variables of interest ... } }
Re: capturing from Input file
by andyford (Curate) on Dec 13, 2007 at 01:06 UTC