Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Pattern Matching and skipping

Reply
Thread Tools

Pattern Matching and skipping

 
 
mattjones@hotmail.co.uk
Guest
Posts: n/a
 
      09-06-2006
Hi,

I've got a small problem....im searching for words in a sentence (from
a log file) then pulling the sentence and putting it in a database. My
problem is that if the word and thus the sentence is no in the log file
- it is missing the log file out altogether and now recording them in
the database.
Is there a way of telling the program to look for these words - and if
they are not there - just skip that pattern (leave the field blank) and
move to the next pattern?

<SNIP>

while (<LOG>) {
if (/FASTSEARCH|conflicting/) {
my @lines = split /\n/; {
foreach my $fast (@lines) {

while (<LOG>) {
if (/elapsed/) {
my @lines = split /\n/; {
foreach my $elapsed2 (@lines) {

So, the script looks for FASTSEARCH and conflicting......if these are
not present i'd like the script to leave the field blank and move to
the next pattern (elapsed).
At the moment my script works but a few of the log files don't contain
FASTSEARCH or conflicting and so are not getting read into the database
(presumably because i am just doing loop after loop and if it doesn't
pick up either of these words it breaks the chain!)

Thanks

Matt (PERL Newbie!)

 
Reply With Quote
 
 
 
 
Mumia W.
Guest
Posts: n/a
 
      09-06-2006
On 09/06/2006 09:24 AM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Hi,
>
> I've got a small problem....im searching for words in a sentence (from
> a log file) then pulling the sentence and putting it in a database. My
> problem is that if the word and thus the sentence is no in the log file
> - it is missing the log file out altogether and now recording them in
> the database.
> Is there a way of telling the program to look for these words - and if
> they are not there - just skip that pattern (leave the field blank) and
> move to the next pattern?
>
> <SNIP>
>
> while (<LOG>) {
> if (/FASTSEARCH|conflicting/) {
> my @lines = split /\n/; {
> foreach my $fast (@lines) {
>
> while (<LOG>) {
> if (/elapsed/) {
> my @lines = split /\n/; {
> foreach my $elapsed2 (@lines) {
>
> So, the script looks for FASTSEARCH and conflicting......if these are
> not present i'd like the script to leave the field blank and move to
> the next pattern (elapsed).
> At the moment my script works but a few of the log files don't contain
> FASTSEARCH or conflicting and so are not getting read into the database
> (presumably because i am just doing loop after loop and if it doesn't
> pick up either of these words it breaks the chain!)
>
> Thanks
>
> Matt (PERL Newbie!)
>


Use the 'else' section of the if statement to tell perl what
to do when FASTSEARCH and conflicting are not there.

if (condition) {
... code ...
} else {
... code ...
}



 
Reply With Quote
 
 
 
 
mattjones@hotmail.co.uk
Guest
Posts: n/a
 
      09-06-2006

>
> Use the 'else' section of the if statement to tell perl what
> to do when FASTSEARCH and conflicting are not there.
>
> if (condition) {
> ... code ...
> } else {
> ... code ...
> }


ok thanks - i thought i had tried that today but ill give it another
shot tomorrow... perhaps i put the curly brackets in the wrong way!

 
Reply With Quote
 
mattjones@hotmail.co.uk
Guest
Posts: n/a
 
      09-07-2006
Ok, this hasn't seemed to work - either i am putting the } in the wrong
place (and i think i have tried most things)!

So i've tried:

while (<LOG>) {
if (/elapsed/) {
my @lines = split /\n/; {
foreach my $elapsed1 (@lines) {
{
while (<LOG>) {
if (/FASTSEARCH|conflicting/) {
} else {next } # this is where i
am having trouble
my @lines = split /\n/; {
foreach my $fast (@lines) {

while (<LOG>) {
if (/elapsed/) {
my @lines = split /\n/; {
foreach my $elapsed2 (@lines) {

So, i want the code to look for FASTSEARCH or conflicting and if they
aren't there - leave it blank but continue with the while loops.

 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      09-07-2006
<(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Ok, this hasn't seemed to work - either i am putting the } in the wrong
> place (and i think i have tried most things)!
>
> So i've tried:
>
> while (<LOG>) {
> if (/elapsed/) {
> my @lines = split /\n/; {


I haven't followed this thread, but the split() above is nonsense. If
you have read a line (with standard $/) the text contains at most one
line feed at he end. Splitting on linefeed doesn't do more than chomp.

Since it appears multiple times in your code, here and in your OP, I
thought I'd mention it.

Anno
 
Reply With Quote
 
MattJ83
Guest
Posts: n/a
 
      09-07-2006
> > while (<LOG>) {
> > if (/elapsed/) {
> > my @lines = split /\n/; {

>
> I haven't followed this thread, but the split() above is nonsense. If
> you have read a line (with standard $/) the text contains at most one
> line feed at he end. Splitting on linefeed doesn't do more than chomp.
>
> Since it appears multiple times in your code, here and in your OP, I
> thought I'd mention it.
>
> Anno


When i remove split from my code however, the code doesn't work?!

 
Reply With Quote
 
MattJ83
Guest
Posts: n/a
 
      09-07-2006
Right - i thought it might be btter if i just paste all of the code i
have done:

#!/usr/central/bin/perl
use strict ;
#use warnings;
use DBI;

my @files= </home/USERNAME/logs/*.log>;
foreach my $file (@files) {

open (LOG,</home/USERNAME/logs/*.log>) or die "can't open LOG: $!\n";

while (<LOG>) {
if (/updates table/) {
my @lines = split /\n/; {
foreach my $info (@lines) {

while (<LOG>) {
if (/elapsed/) {
my @lines = split /\n/; {
foreach my $elapsed1 (@lines) {

while (<LOG>) {
if (/conflicting|FASTSEARCH/) {
my @lines = split /\n/; {
foreach my $fast (@lines) {

while (<LOG>) {
if (/elapsed/) {
my @lines = split /\n/; {
foreach my $elapsed2 (@lines) {

while (<LOG>) {
if (/inversions/) {
my @lines = split /\n/; {
foreach my $inversions (@lines) {

while (<LOG>) {
if (/elapsed/) {
my @lines = split /\n/; {
foreach my $elapsed3 (@lines) {

close(LOG) ;

my $dbh = DBI ->connect("dbi:Oracle:SERVER", "DATABASE", "PASSWORD")
or die "couldn't connect to database: $DBI::errstr\n";

$dbh->do("insert into LOGS values ('$file', '$info', '$elapsed1',
'$fast', '$elapsed2', '$inversions', '$elapsed3')") or die ("inse
rting data failure: $!\n");

$dbh->disconnect;
}}}}}}}}}}}}}}}}}}}}}}}}}
exit;

And all i want it to do is skip the line if it can't match the words
specified!!!
I just can't get the else or elseif statements to work...........

Sorry for the script - it isn't to brilliant but im new and it does
what i want it to do!!!

 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      09-07-2006
MattJ83 <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> > > while (<LOG>) {
> > > if (/elapsed/) {
> > > my @lines = split /\n/; {

> >
> > I haven't followed this thread, but the split() above is nonsense. If
> > you have read a line (with standard $/) the text contains at most one
> > line feed at he end. Splitting on linefeed doesn't do more than chomp.
> >
> > Since it appears multiple times in your code, here and in your OP, I
> > thought I'd mention it.
> >
> > Anno

>
> When i remove split from my code however, the code doesn't work?!


Sure, just deleting the line will break it because the assignment to
@lines goes away too. The split() doesn't do anything useful, however.

With a little more context, your code is:

while (<LOG>) {
if (/elapsed/) {
my @lines = split /\n/; {
foreach my $elapsed1 (@lines) {
# ...

Change this to (untested):

while ( <LOG> ) {
chomp;
if ( /elapsed/ ) {
# ...

that is, drop both the line with split() and the next one "foreach ...".
The content of $_, which is what matters, will be the same in both
cases. The "foreach" loop would run only one time anyway.

Anno
 
Reply With Quote
 
David Squire
Guest
Posts: n/a
 
      09-07-2006
MattJ83 wrote:
> Right - i thought it might be btter if i just paste all of the code i
> have done:
>
> #!/usr/central/bin/perl
> use strict ;
> #use warnings;
> use DBI;
>
> my @files= </home/USERNAME/logs/*.log>;
> foreach my $file (@files) {
>
> open (LOG,</home/USERNAME/logs/*.log>) or die "can't open LOG: $!\n";


Surely you want to open each file in succession here. I don't know what
happens when you pass the result of a glob as the filename to open, but
I would bet that what you really wanted here was something like:

open (my $LOG, '<', $file) or die "can't open $file: $!\n";

(Note the use of a lexical file handle and the three argument form of
open. They're good habits to get into.)

>
> while (<LOG>) {


This gets a *single line* from the filehandle LOG and stores it
implicitly in $_

> if (/updates table/) {
> my @lines = split /\n/; {


As has already been pointed out, you only have a single line to work
with here. You can't split into multiple lines on \n, since there is
only one \n, and the end of the line.

You need to change your logic to loop over the lines one by one.

> foreach my $info (@lines) {
>
> while (<LOG>) {
> if (/elapsed/) {
> my @lines = split /\n/; {
> foreach my $elapsed1 (@lines) {
>
> while (<LOG>) {
> if (/conflicting|FASTSEARCH/) {
> my @lines = split /\n/; {
> foreach my $fast (@lines) {
>
> while (<LOG>) {
> if (/elapsed/) {
> my @lines = split /\n/; {
> foreach my $elapsed2 (@lines) {
>
> while (<LOG>) {
> if (/inversions/) {
> my @lines = split /\n/; {
> foreach my $inversions (@lines) {
>
> while (<LOG>) {
> if (/elapsed/) {
> my @lines = split /\n/; {
> foreach my $elapsed3 (@lines) {
>
> close(LOG) ;


[snip]

Indentation would help a lot too.


DS


 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      09-07-2006
MattJ83 <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> > > while (<LOG>) {
> > > if (/elapsed/) {
> > > my @lines = split /\n/; {

> >
> > I haven't followed this thread, but the split() above is nonsense. If
> > you have read a line (with standard $/) the text contains at most one
> > line feed at he end. Splitting on linefeed doesn't do more than chomp.
> >
> > Since it appears multiple times in your code, here and in your OP, I
> > thought I'd mention it.
> >
> > Anno

>
> When i remove split from my code however, the code doesn't work?!


Sure, you threw out the baby with the bath water. The assignment to
@lines also goes away if you just delete the line.

The point is, @lines will only ever contain one element, the current
line minus its line feed. The same would be achieved by (untested)

while ( <LOG> ) {
chomp;
if ( /elapsed/ ) {
my @lines = ( $_);

I seem to remember that a loop over @lines follows. Both the variable
@lines and the loop can presumably go away too.

Anno
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Regex testing and UTF8 awarenes or Regex and numeric pattern matching sln@netherlands.com Perl Misc 2 03-10-2009 03:51 AM
Help with Pattern matching. Matching multiple lines from while reading from a file. Bobby Chamness Perl Misc 2 05-03-2007 06:02 PM
Pattern Matching Given # of Characters and no String Input; use RegularExpressions? Synonymous Python 10 04-22-2005 07:56 AM
[perl-python] text pattern matching, and expressiveness Xah Lee Python 4 02-11-2005 09:11 PM
Pattern matching : not matching problem Marc Bissonnette Perl Misc 9 01-13-2004 05:52 PM



Advertisments