Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Few lines of Code Needed 1

Status
Not open for further replies.

nanohurtz

Programmer
Mar 25, 2002
15
US
well..since noone helped with the Pattern search part of my request today, I managed to muster up the rather lengthy script on my own. It was successfully tested using optiPerl3 (my favorite)..flawless. One problem though, it's too long. Can some one tighten this code up by a few lines and still produce the same results??

#!/usr/bin/perl -w

open(IN, &quot;< jobreader.txt&quot;) or die &quot;Cannot open file for read\n&quot;;
open(OUT, &quot;> jobreaderout.txt&quot;) or die &quot;Cannot open file for write\n&quot;;
my ($sname, $jname, $commd, $logon, $ descr, $recvy);

while(<IN>) {
chomp;

if (m/(.*)#(.*) (SCRIPTNAME||DOCOMMAND) (.*)$/) {
$sname=$1, $jname=$2, $commd=$4;
}elsif (m/(.*) (SCRIPTNAME||DOCOMMAND) (.*)$/) {
$sname=&quot;TRAP999A&quot;, $jname=$1, $commd=$3;
}elsif (m/(STREAMLOGON) (.*)$/) {
$logon=$2;
}elsif (m/(DESCRIPTION) (.*)$/) {
$descr=$2;
}elsif (m/(RECOVERY) (.*)$/) {
$recvy=$2;
print OUT &quot;$sname\|$jname\|$commd\|$logon\|$descr\|$recvy\n&quot;;
$sname = &quot;&quot;, $jname=&quot;&quot;, $commd=&quot;&quot;;
}
}
Close (IN);
Close (OUT);

SAMPLE IN.TXT FILE IN

MBQR123A#RPM123DP SCRIPTNAME &quot;/usr/bin/tryout.sh&quot;
STREAMLOGON &quot;root&quot;
DESCRIPTION &quot;Experimental Script&quot;
RECOVERY STOP

FRTT544A#RTD123DP DOCOMMAND &quot;/usr/ben/hammerhead.sh&quot;
STREAMLOGON &quot;root&quot;
DESCRIPTION &quot;Some silly script&quot;
RECOVERY STOP

JHGF733A#GGG366DP SCRIPTNAME &quot;/usr/local/sniffer.sh&quot;
STREAMLOGON &quot;fred&quot;
DESCRIPTION &quot;Checks for Ports&quot;
RECOVERY STOP

REDF511 SCRIPTNAME &quot;/usr/local/thetrap.sh&quot;
STREAMLOGON &quot;tuff&quot;
DESCRIPTION &quot;Tricky script B1&quot;
RECOVERY STOP

SAMPLE OUT.TXT FILE

MBQR123A|RPM123DP|&quot;/usr/bin/tryout.sh&quot; |&quot;root&quot; |&quot;Experimental Script&quot; |STOP
FRTT544A|RTD123DP|&quot;/usr/ben/hammerhead.sh&quot; |&quot;root&quot; |&quot;Some silly script&quot; |STOP
JHGF733A|GGG366DP|&quot;/usr/local/sniffer.sh&quot; |&quot;fred&quot; |&quot;Checks for Ports&quot; |STOP
TRAP999A|REDF511|&quot;/usr/local/thetrap.sh&quot; |&quot;tuff&quot; |&quot;Tricky script B1&quot; |STOP
 
One way. No prettier :-(
Code:
%actions = (
    '^(.+)#(.+) (SCRIPTNAME||DOCOMMAND) (.*)$'
    => sub { push @out, $1, $2, $4 },
    '^([^#]+) (SCRIPTNAME||DOCOMMAND) (.*)$'
    => sub { push @out, &quot;TRAP999A&quot;, $1, $3 },
    'STREAMLOGON' => sub { push @out, (split(&quot; &quot;, $_, 2))[1] },
    'DESCRIPTION' => sub { push @out, (split(&quot; &quot;, $_, 2))[1] },
    'RECOVERY'    => sub { push @out, (split(&quot; &quot;, $_, 2))[1];
        local $&quot; = &quot;|&quot;; print &quot;@out\n&quot;; @out = () }
);
 
my @out;
while( <IN> ) {
    next if /^$/;
    chomp; s/^\s+//; s/\s+$//;
    foreach my $pat ( keys %actions ) {
        &{$actions{$pat}} if /$pat/;
    }
}
Cheers, Neil
 
Minor refinement. Notice you should be using a single pipe character for regular expression alternatives, and not two:
Code:
%actions = (
    '(SCRIPTNAME|DOCOMMAND)'
    => sub { my @f = split( /(?:#|\s)+/, $_ );
           unshift @f, &quot;TRAP999A&quot; if ( $#f == 2 );
           push @out, (@f)[0,1,3] },
    'STREAMLOGON' => sub { push @out, (split(&quot; &quot;, $_, 2))[1] },
    'DESCRIPTION' => sub { push @out, (split(&quot; &quot;, $_, 2))[1] },
    'RECOVERY'    => sub { push @out, (split(&quot; &quot;, $_, 2))[1];
        local $&quot; = &quot;|&quot;; print &quot;@out\n&quot;; @out = () }
);
 
my @out;
while( <IN> ) {
    next if /^$/;
    chomp; s/^\s+//; s/\s+$//;
    foreach my $pat ( keys %actions ) {
        &{$actions{$pat}} if /$pat/;
    }
}
Cheers, Neil
 
Yet another version. Still no shorter :-(
Code:
%actions = (
    '^(.+)#(.+) (?:SCRIPTNAME|DOCOMMAND) (.+)'
    => sub { push @out, $1, $2, $3 },
    '^([^#]+) (?:SCRIPTNAME|DOCOMMAND) (.+)'
    => sub { push @out, &quot;TRAP999A&quot;, $1, $2 },
    'STREAMLOGON (.+)' => sub { push @out, $1 },
    'DESCRIPTION (.+)' => sub { push @out, $1 },
    'RECOVERY (.+)'    => sub { push @out, $1;
        local $&quot; = &quot;|&quot;; print &quot;@out\n&quot;; @out = () }
);
 
my @out;
while( <IN> ) {
    next if /^$/;
    chomp; s/^\s+//; s/\s+$//;
    foreach my $pat ( keys %actions ) {
        &{$actions{$pat}} if /$pat/;
    }
}
Cheers, Neil
 
Minor speedup:
Code:
&{$actions{$pat}}, last if /$pat/;
The last keyword short circuits the current line pattern matching as soon as a valid pattern was found.
Cheers, Neil
 
Wow, looks great Neil. How do I incorporate the I/O (reading and writing to and from files) portion to your newly modified code?
 
Use the same open /close calls as in your original code. Then simply modify the print statement from:
[tt]
print &quot;@out\n&quot;;
[/tt]
To:
[tt]
print OUT &quot;@out\n&quot;;
[/tt]
Cheers, Neil
 
Cool, I got it. I will definitely need to warm up to the power of arrays. Thanks again
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top