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.

Edited 5 Years Ago by anraevlus18: n/a

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;

Edited 5 Years Ago by k_manimuthu: n/a

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)

Comments
Good advice.

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;
This article has been dead for over six months. Start a new discussion instead.