Hi,

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?
Is it possible to do this with one single grep?

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

Please help me.

use strict;
use warnings;

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

# join the array element in a string
my $path = join ' ', @file_list;

# process each elements
foreach my $element (@file_list)
{
	### Replace the elements and get the counts
	my $count = $path=~ s{/?$element\s*}{ }g;
	### Push the elements when count is 1
	push @expect, $element if ($count == 1);
}

# print the results
print "\n$_" for @expect;

Hi Manimuthu,

Thanks for your reply..But this logic even i have tried. I wanted to use one single grep command for both operations. Is there a way to do this?

Hi Manimuthu,

Thanks for your reply..But this logic even i have tried. I wanted to use one single grep command for both operations. Is there a way to do this?

My advice? Don't bother, unless it's a serious performance barrier (in which case I suspect you wouldn't want to keep the whole thing in an array at once). Make the code as clear as you can and don't worry about how many times it loops over some array.

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." (attributed to Brian Kernighan)

commented: Good advice. +2

Hi Manimuthu,

Thanks for your reply..But this logic even i have tried. I wanted to use one single grep command for both operations. Is there a way to do this?

#!/usr/bin/perl
use strict;
use warnings;

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.
my %filenames;
my $firstpass = 1;
my @unique_files = grep {
                        if ($firstpass == 1){
                            foreach (@unique){
                                my @arr = split('/');
                                $filenames{$arr[-1]}++;
                            }
                            $firstpass = 0;
                        }
                        defined($filenames{$_}) && $filenames{$_} == 1
                    } @unique;

print "Unique filename(s):\n", join ', ', @unique_files;