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/