Solved

How to parse below text pattern using perl

Posted on 2011-03-02
8
248 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
Comment Utility
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
Comment Utility

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
Comment Utility
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
 
LVL 16

Expert Comment

by:sjklein42
Comment Utility
Was there something wrong with my solution?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 28

Expert Comment

by:FishMonger
Comment Utility
>> 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
Comment Utility
What does this line do?
if ( /^START/../^STOP/ )

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

Expert Comment

by:FishMonger
Comment Utility
.. 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
Comment Utility
Thank you! :-)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

On Microsoft Windows, if  when you click or type the name of a .pl file, you get an error "is not recognized as an internal or external command, operable program or batch file", then this means you do not have the .pl file extension associated with …
A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
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…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.

763 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

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now