On 18/12/2010 19:21, Arun G Nair wrote:

Sooraj S wrote:

I have an array file_list which contains absolute/relative paths of
files. I want to remove duplicate elements and elements whose
filenames(not the path) are same. How can i do this using grep and
hash?

My code
=======
my @file_list= qw(aaa ddd bbb/aaa ccc ddd kkk/ddd hhh);
my %exist=();
#To remove duplicate elements.
my @unique = grep { ! $exist { $_ }++ } @file_list;
#To remove elements with same filename.
#Please write your code here.

O/p should be =>  ccc hhh

Is it possible to do both deletion operations with one single grep?

Please help me..

Try:

[~]$ perl -MFile::Basename -le '@file_list = qw(aaa ddd bbb/aaa ccc
ddd kkk/ddd hhh); $,="," ; print grep { $h{$_} == 1 } grep { ++$h{$_}
} map { basename($_) } @file_list;'
ccc,hhh

[~]$ perl -le '@file_list = qw(aaa ddd bbb/aaa ccc ddd kkk/ddd hhh);
$,="," ; print grep { $h{$_} == 1 } grep { ++$h{$_} } map { (split
/\//)[-1] } @file_list;'
ccc,hhh

These solutions have the disadvantage of removing all ocurrences of
identically-pathed files, so in a list like

  my @file_list = qw(aaa ddd bbb/aaa ccc ccc ddd kkk/ddd hhh);

all files except hhh are filtered out. It also removes the path from
the original filespec.

I suggest something like the program below.

HTH,

Rob


use strict;
use warnings;

my @file_list = qw(aaa ddd bbb/aaa ccc ccc ddd bbb/fff kkk/ddd hhh);

my @filtered = do {

  my %dup;

  foreach (@file_list) {
    m{(.*?)([^/]+)$} or die "Invalid filespec '$_'";
    $dup{$2}{$1}++;
  }

  map { join '', (keys %{$dup{$_}})[0], $_ }
  grep { keys %{$dup{$_}} == 1 } keys  %dup;
};

print "@filtered\n";

**OUTPUT**

hhh bbb/fff ccc

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to