Finding consecutive lines

Discussion in 'Perl Misc' started by Peter, Nov 5, 2004.

  1. Peter

    Peter Guest

    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
    Peter, Nov 5, 2004
    #1
    1. Advertising

  2. Peter <> wrote:


    > 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.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Nov 5, 2004
    #2
    1. Advertising

  3. Peter

    Brad Baxter Guest

    On Fri, 5 Nov 2004, Peter wrote:

    > 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
    Brad Baxter, Nov 5, 2004
    #3
  4. Brad Baxter <> wrote:

    > On Fri, 5 Nov 2004, Peter wrote:
    >
    >> 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
    David K. Wall, Nov 5, 2004
    #4
  5. Peter

    Guest

    (Peter) wrote:
    > 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

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Nov 5, 2004
    #5
  6. Peter

    Brad Baxter Guest

    On Fri, 5 Nov 2004, David K. Wall wrote:

    > Brad Baxter <> wrote:
    >
    > > On Fri, 5 Nov 2004, Peter wrote:
    > >
    > >> 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
    Brad Baxter, Nov 5, 2004
    #6
  7. On 5 Nov 2004 06:46:16 -0800, (Peter)
    wrote:

    >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
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Nov 5, 2004
    #7
  8. On Fri, 05 Nov 2004 17:20:46 -0000, "David K. Wall"
    <> wrote:

    >#!/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
    --
    {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{pop^pop}->(map substr
    (($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
    ..'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
    256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,
    Michele Dondi, Nov 6, 2004
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?bWc=?=
    Replies:
    2
    Views:
    2,057
    =?Utf-8?B?bWc=?=
    Jun 2, 2004
  2. baptiste Auguié

    extracting values from consecutive lines

    baptiste Auguié, Oct 17, 2007, in forum: Ruby
    Replies:
    15
    Views:
    225
    7stud --
    Oct 18, 2007
  3. baptiste Auguié

    extract consecutive lines of data

    baptiste Auguié, Nov 24, 2007, in forum: Ruby
    Replies:
    8
    Views:
    122
    Robert Dober
    Nov 25, 2007
  4. sbk
    Replies:
    5
    Views:
    147
  5. Replies:
    9
    Views:
    138
    A. Sinan Unur
    Aug 22, 2008
Loading...

Share This Page