tags:

views:

39

answers:

2

I'm using this code to remove all duplicates, but I have a need to remove only specific duplicates and leave all others untouched.

In my case if the line matches /^\s+INDEX 00 \d\d:\d\d:\d\d$/ then keep each unique first line, but delete duplicates, and keep all lines that don't match the regex.

tie my @lines, 'Tie::File', $fn or die "could not tie file: $!";
my %seen;
@lines = grep(!$seen{$_}++, @lines);
untie @lines;
+1  A: 
tie my @lines, 'Tie::File', $fn or die "could not tie file: $!";
my %seen;
@lines = grep(!/^\s+INDEX 00 \d\d:\d\d:\d\d$/ || !$seen{$_}++, @lines);
untie @lines;
runrig
Yes, I want to filter a certain type of duplicate.Nice work.Thanks.
thebourneid
@Zaid: This does filter the certain types of duplicates that the OP wants. Are you critiquing this version or the version I had up for about the first minute?
runrig
@runrig : My bad, I had a long day yesterday...
Zaid
+1  A: 
@lines = ( $array[0],
             grep { not /^\s+INDEX 00 \d\d:\d\d:\d\d$/ } @lines[1..$#lines] );

Explanation

  • An array slice is taken to ignore the first element while filtering with grep
  • grep filters through all elements that don't match the regex
  • The resultant array is assigned to @lines
Zaid
unshift returns the new number of elements in the array. This doesn't work at all. And I think you misunderstood the slightly badly worded question.
runrig
@runrig : Thanks for the head-up, I've updated my answer accordingly.
Zaid