5

I want to get all elements in clearcase, store them in an array, and then remove the symbolic links from that array. Problem is I don't know how to remove all elements in one array that are contained in another array since I'm new to perl.

Bellow is my code so far.

foreach ${dir} (@{code_vob_list}) 
{
    ${dir} =~ s/\n//;
    open(FIND_FILES, "$cleartool find ${dir} -type f -exec 'echo \$CLEARCASE_PN' |") or die "Can't stat cleartool or execute : $!\n"; #This command gets all files
    @{files_found} = <FIND_FILES>;

    open(SYMBOLIC_FIND_FILES, "$cleartool find ${dir} -type l -exec 'echo \$CLEARCASE_PN' |") or die "Can't stat cleartool or execute : $!\n"; #This command get all symbolic links
    @{symbolic_files_found} = <SYMBOLIC_FIND_FILES>;
    #Filter away all strings contained in @{symbolic_files_found} from @{files_found}
    foreach my ${file} (@{files_found}) 
    {
        #Here I will perform my actions on @{files_found} that not contains any symbolic link paths from @{symbolic_files_found}
    }
}

Thanks in advance

2
  • 2
    Where did you learn to put all your identifiers inside braces? I hope you realise that it's unnecessary, and I believe it makes the code less readable Commented Jun 17, 2015 at 11:11
  • Try looking at File::Find for tasks like this. Commented Jun 17, 2015 at 11:26

2 Answers 2

10

To filter an array, you can use grep:

my @nonlinks = grep { my $f = $_;
                      ! grep $_ eq $f, @symbolic_files_found }
               @files_found;

But it's usually cleaner to use a hash.

my %files;
@files{ @files_found } = ();            # All files are the keys.
delete @files{ @symbolic_files_found }; # Remove the links.
my @nonlinks = keys %files;
Sign up to request clarification or add additional context in comments.

Comments

2

I suggest that you install and use List::Compare. The code would look like this

As I wrote in my comment, I'm not sure if you prefer to write your identifiers like that, and I'm also unclear if you've avoided backticks `...` (same as qx{...}) in favour of a pipe open for a reason, but this is closer to how I'd write your code

If you prefer, get_unique has a synonym get_Lonly which you may find more expressive

use List::Compare;

for my $dir ( @code_vob_list ) {

    chomp $dir;

    my @files_found = qx{$cleartool find $dir -type f -exec 'echo \$CLEARCASE_PN'};
    chomp @files_found;

    my @symbolic_files_found = qx{$cleartool find $dir -type l -exec 'echo \$CLEARCASE_PN'};
    chomp @symbolic_files_found;

    my $lc = List::Compare->new('--unsorted', \@files_found, \@symbolic_files_found);
    my @unique = $lc->get_unique;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.