Finding consecutive lines

P

Peter

I need to parse a file looking for patterns in 5 consecutive lines.
e.g.

I want to find 5 consecutive lines with "abc" in first line, "def" in second,
"efg" in third etc.

How can I do something like this..


Thanks in advance,
Peter
 
T

Tad McClellan

I want to find 5 consecutive lines with "abc" in first line, "def" in second,
"efg" in third etc.

How can I do something like this..


Buffer the 4 previous lines.
 
B

Brad Baxter

I need to parse a file looking for patterns in 5 consecutive lines.
e.g.

I want to find 5 consecutive lines with "abc" in first line, "def" in second,
"efg" in third etc.

How can I do something like this..


Thanks in advance,
Peter

What have you tried so far? :)

Regards,

Brad

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

my @f = qw( abc def ghi jkl mno );
my @s;
while( <DATA> ) {
push @s, $_;
shift @s if @s > 5;
next unless @s == 5;
print " @s\n" if
$s[0] =~ /$f[0]/ and
$s[1] =~ /$f[1]/ and
$s[2] =~ /$f[2]/ and
$s[3] =~ /$f[3]/ and
$s[4] =~ /$f[4]/;
}
__DATA__

hey abc
there def abc
june ghi def abc
bug jkl ghi def abc
lets mno jkl ghi def abc
get mno jkl ghi def
in mno jkl ghi
the mno jkl
mud mno

__END__
hey abc
there def abc
june ghi def abc
bug jkl ghi def abc
lets mno jkl ghi def abc

there def abc
june ghi def abc
bug jkl ghi def abc
lets mno jkl ghi def abc
get mno jkl ghi def

june ghi def abc
bug jkl ghi def abc
lets mno jkl ghi def abc
get mno jkl ghi def
in mno jkl ghi

bug jkl ghi def abc
lets mno jkl ghi def abc
get mno jkl ghi def
in mno jkl ghi
the mno jkl

lets mno jkl ghi def abc
get mno jkl ghi def
in mno jkl ghi
the mno jkl
mud mno
 
D

David K. Wall

Brad Baxter said:
I need to parse a file looking for patterns in 5 consecutive
lines. e.g.

I want to find 5 consecutive lines with "abc" in first line,
"def" in second, "efg" in third etc.
[snip]

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

my @f = qw( abc def ghi jkl mno );
my @s;
while( <DATA> ) {
push @s, $_;
shift @s if @s > 5;
next unless @s == 5;
print " @s\n" if
$s[0] =~ /$f[0]/ and
$s[1] =~ /$f[1]/ and
$s[2] =~ /$f[2]/ and
$s[3] =~ /$f[3]/ and
$s[4] =~ /$f[4]/;
}

I like this a little better because it doesn't require maintenance if
the number of patterns changes.



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

my @buffer;
my @pattern = qw(abc def ghi jkl mno);
while (<DATA>) {
push @buffer, $_;
next if @buffer != @pattern;
my $matches = grep /1/,
map $buffer[$_] =~ /$pattern[$_]/,
0 .. $#pattern;
print @buffer if $matches == @pattern;
shift @buffer;
}


__DATA__
jdfk jkdfh bl
dfjkv dfjk
dfjdj
abc these
def are
ghi the
jkl lines
mno we want
hj dfvhj d
jkfh vblsdjk
jdkf hld
 
C

ctcgag

I need to parse a file looking for patterns in 5 consecutive lines.
e.g.

I want to find 5 consecutive lines with "abc" in first line, "def" in
second, "efg" in third etc.

How can I do something like this..

If your file fits in memory:

warn "Untested";
$file =~ /^(.*abc.*\n.*def.*\n.*efg.*)$/m;

If course you presumably want to do something with these lines, but you
didn't say what that was.

Xho
 
B

Brad Baxter

Brad Baxter said:
I need to parse a file looking for patterns in 5 consecutive
lines. e.g.

I want to find 5 consecutive lines with "abc" in first line,
"def" in second, "efg" in third etc.
[snip]

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

my @f = qw( abc def ghi jkl mno );
my @s;
while( <DATA> ) {
push @s, $_;
shift @s if @s > 5;
next unless @s == 5;
print " @s\n" if
$s[0] =~ /$f[0]/ and
$s[1] =~ /$f[1]/ and
$s[2] =~ /$f[2]/ and
$s[3] =~ /$f[3]/ and
$s[4] =~ /$f[4]/;
}

I like this a little better because it doesn't require maintenance if
the number of patterns changes.



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

my @buffer;
my @pattern = qw(abc def ghi jkl mno);
while (<DATA>) {
push @buffer, $_;
next if @buffer != @pattern;
my $matches = grep /1/,
map $buffer[$_] =~ /$pattern[$_]/,
0 .. $#pattern;
print @buffer if $matches == @pattern;
shift @buffer;
}

I agree that's better. I see you also optimized away an unnecessary
comparison. :)

Regards,

Brad
 
M

Michele Dondi

I want to find 5 consecutive lines with "abc" in first line, "def" in second,
"efg" in third etc.

How can I do something like this..

Slurp the whole file in and use a regex! If the whole file is huge,
then maintain a buffer and join lines five at a time as you read new
ones.


Michele
 
M

Michele Dondi

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

my @buffer;
my @pattern = qw(abc def ghi jkl mno);
while (<DATA>) {
push @buffer, $_;
next if @buffer != @pattern;

While your scheme is terse and elegant in that it fills in the buffer
as needed, but even if I'm not one of those paranoids about
efficiency, it bothers me a little that the check is done for all
lines, including the majority of them that would not require it. I'd
pre-load it instead.
my $matches = grep /1/,
map $buffer[$_] =~ /$pattern[$_]/,
0 .. $#pattern;

Well, I'm a big fan of map() and grep(), but in this case it seems to
me an overhead to use them. What about a simple counter instead? Also,
another source of inefficiency is in the fact that all patterns are
tried even if some of them fail, thus...
print @buffer if $matches == @pattern;
shift @buffer;
}

....all in all I'd rewrite it as


#!/usr/bin/perl

use strict;
use warnings;

my @pattern = qw(abc def ghi jkl mno);
my @buffer = (0, map scalar <>, 1..$#pattern);

LINE: while (<>) {
shift @buffer; push @buffer, $_;
$buffer[$_] =~ /$pattern[$_]/ or
next LINE for 0..$#pattern;
print @buffer;
}

__END__


Michele
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top