in reply to to delete a set of specific lines in a file

First of all sugar++ for giving us sample input and reference output as well as a clear description of what your problem is.

In addition to what the others have said: You build a fairly large regex from @dels, which might slow down things (if the number of items is in the millions).

I'd suggest to use a hash instead of @dels:

#!/usr/bin/perl use strict; use warnings; my $prev1=0;my $prev2=0;my @dels; open my $file, '<', 'data.txt' or die "Can't open file: $!@"; my %dels; while (<$file>) { # the \. prevents . from matching any character my @spl = split(/\.[fr]/, $_); if($prev1 eq $spl[0] && $prev2 eq $spl[1]){ $dels{$spl[0]} = 1; } $prev1=$spl[0];$prev2=$spl[1]; } # reset the file cursor, read from the beginning again seek $file, 0, 0; while (<$file>) { my @spl = split(/\.[fr]/, $_); print unless $dels{$spl[0]}; } close $file;

This version gets rid of @arr entirely, and replaced the regex and @dels with %dels.

Replies are listed 'Best First'.
Re^2: to delete a set of specific lines in a file
by eye (Chaplain) on Dec 05, 2008 at 09:34 UTC
    Going a step further, we can do this in a single pass:
    #!/usr/bin/perl use strict; use warnings; open my $file, '<', 'data.txt' or die "Can't open file: $!@"; my @prev = (); while (my $line = <$file>) { my @spl = split(/(\.[fr])/, $line); if (@prev) { if ($prev[0] ne $spl[0] || $prev[2] ne $spl[2]){ print @prev; } else { @prev = (); next; } } @prev = @spl; } print @prev; close $file;
Re^2: to delete a set of specific lines in a file
by sugar (Beadle) on Dec 05, 2008 at 09:10 UTC
    thank u :) Now the program takes only 2 seconds to output the desired results :)