Solved

How to parse below text pattern using perl

Posted on 2011-03-02
8
251 Views
Last Modified: 2012-05-11
Hello, I have a text file on which I have some data between multiple instance START and STOP. I need to get the data between START and STOP and put in appropriate format like.

<<INPUT>>
START
 queue.queuename.123
 User=abcde    receive
 User=abcdef        send
 User=abcdee       send
STOP
START
 queue.queuename.1234
 User=abcdeq       send
 User=abcdek      send
 User=abcdeo       send
 User=abcder    receive
STOP
START
 queue.queuename.12345
 User=bcder    receive
 User=bcder3       send
 User=bcdere      send
STOP

Open in new window


<<OUTPUT>>
grant queue queue.queuename.123 User=abcde    receive
grant queue queue.queuename.123 User=abcdef        send
grant queue queue.queuename.123 User=abcdee       send

grant queue queue.queuename.1234 User=abcdeq       send
grant queue queue.queuename.1234 User=abcdek      send
grant queue queue.queuename.1234 User=abcdeo       send
grant queue queue.queuename.1234 User=abcder    receive

grant queue queue.queuename.12345 User=bcder    receive
grant queue queue.queuename.12345 User=bcder3       send
grant queue queue.queuename.12345 User=bcdere      send

Open in new window


basically in the START STOP the first line is queue name and below of it is permission so on every permission I want to append the grant queue <queue name> . fex

while parsing

START
 queue.queuename.123
 User=abcde    receive
 User=abcdef        send
 User=abcdee       send
STOP

Open in new window

it would print
grant queue queue.queuename.123 User=abcde    receive
grant queue queue.queuename.123 User=abcdef        send
grant queue queue.queuename.123 User=abcdee       send

Open in new window

Please let me know how can I achieve it. Thanks in advance!
0
Comment
Question by:beer9
8 Comments
 
LVL 16

Accepted Solution

by:
sjklein42 earned 250 total points
ID: 35016967
Try this

$n=0;
while ( <> )
{
    s/[\r\n]//g;
    if ( ( /^START$/ ) && ( $n != 0 ) ) { print "\n"; }
    elsif ( /\s*(queue\.[^\s]*)/i ) { $queue = $1; }
    elsif ( /\s*(User\=[^\s]*)\s+/i )
    {
        print "grant queue $queue $1 $'\n";
    }
    
    $n++;
}

Open in new window


c:\temp>perl foo.pl foo.dat
grant queue queue.queuename.123 User=abcde receive
grant queue queue.queuename.123 User=abcdef send
grant queue queue.queuename.123 User=abcdee send

grant queue queue.queuename.1234 User=abcdeq send
grant queue queue.queuename.1234 User=abcdek send
grant queue queue.queuename.1234 User=abcdeo send
grant queue queue.queuename.1234 User=abcder receive

grant queue queue.queuename.12345 User=bcder receive
grant queue queue.queuename.12345 User=bcder3 send
grant queue queue.queuename.12345 User=bcdere send

c:\temp>

Open in new window

0
 
LVL 28

Assisted Solution

by:FishMonger
FishMonger earned 250 total points
ID: 35017658

E:\TEMP\test>test.pl queue.txt
grant queue  queue.queuename.123  User=abcde    receive
grant queue  queue.queuename.123  User=abcdef        send
grant queue  queue.queuename.123  User=abcdee       send
grant queue  queue.queuename.1234  User=abcdeq       send
grant queue  queue.queuename.1234  User=abcdek      send
grant queue  queue.queuename.1234  User=abcdeo       send
grant queue  queue.queuename.1234  User=abcder    receive
grant queue  queue.queuename.12345  User=bcder    receive
grant queue  queue.queuename.12345  User=bcder3       send
grant queue  queue.queuename.12345  User=bcdere      send

Open in new window

#!/usr/bin/perl

use strict;
use warnings;

die "usage: $0 <filename>\n" if ! @ARGV;

open my $queue_fh, '<', $ARGV[0] or die "failed to open '$ARGV[0]' $!";

my $queue;
while ( <$queue_fh> ) {

    chomp;
    
    if ( /^START/../^STOP/ ) {
        next if /^(START|STOP)/;
        $queue = $_ if /queue/;        
        print "grant queue $queue $_\n" if /User/;
    }
}

Open in new window

0
 
LVL 28

Expert Comment

by:FishMonger
ID: 35017729
I forgot that you wanted to separate the groups.  Here's the adjustment that does that.

if ( /^START/../^STOP/ ) {
        next if /^START/;
        $queue = $_ if /queue/;        
        print "grant queue $queue $_\n" if /User/;
        print "\n" if /STOP/;
    }

Open in new window

0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 16

Expert Comment

by:sjklein42
ID: 35017779
Was there something wrong with my solution?
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 35017991
>> Was there something wrong with my solution?

No not really, but it depends on your point of view.  Your solution does provide the proper results, but there are a couple things I'd change.

1)  You're not running under strictures and as far as we can tell, you also didn't enable warnings.  The 2 pragmas should be in every script and IMO should be in posted solutions.

2)  [^\s]  is better written as: \S

3)  I prefer to open an actual filehandle and include error handling instead of simply using the bare <> diamond operator.

The actual reason I posted my solution was to provide a different approach and point of view.  Perl's moto is TMTOWTDI (There's More Than One Way To Do It)
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 35018201
What does this line do?
if ( /^START/../^STOP/ )

I've never seen .. used to join two regexes.
0
 
LVL 28

Expert Comment

by:FishMonger
ID: 35018266
.. and ... are the flip-flop operators.

When the first regex matches the if test evaluates to true and remains true until after the second regex matches.

http://www.google.com/search?hl=en&client=firefox-a&hs=hso&rls=org.mozilla%3Aen-US%3Aofficial&q=perl+flip-flop+operator&aq=f&aqi=g1&aql=&oq=
0
 

Author Closing Comment

by:beer9
ID: 35059599
Thank you! :-)
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
In the distant past (last year) I hacked together a little toy that would allow a couple of Manager types to query, preview, and extract data from a number of MongoDB instances, to their tool of choice: Excel (http://dilbert.com/strips/comic/2007-08…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question