[Za-pm] loop adding \n to array ??

Jonathan McKeown jonathan at hst.org.za
Thu Jun 29 08:23:53 PDT 2006


On Thursday 29 June 2006 07:37, Gregory Machin wrote:

> find sub { push(@tmp ,$File::Find::name, -d && '/', "\n") }, $tmp_dir;
>
> #find all files starting with a plus
> foreach (@tmp) {
>
>     $_ =~ s/$tmp_dir\/// ; # remove the path to the input working dir so
> only
>                    # the files and directories in the working dir are used
>     $_ =~ s/\/$//;         #remove trailing "/"
>     # /^\+\w+/i  filter all files starting with "+"
>     if ($_ =~ /^\+\w+/i ){ push(@del_files, $_); $_ = "0"; } # filter and
> pass files starting with + to @del_files for removale
>
>     #print "$_";
>     if ($_ ne "0"){
>         push(@ctr_file , "$_");
>         print "$_";
>     }
> }

Nick Cleaton pointed out that in the find line, you're pushing three values 
onto the @tmp array for each filename, which accounts for your "\n"s. The 
middle value is either an empty string, for non-directories, or '/' for 
directories. / is not the ideal value to have occurring in a list of files 
and directories for deletion.

Depending whether you need the @ctr_files list or not, you might try either

find sub { push @tmp, $File::Find::name }, $tmp_dir;
for my $file (@tmp) {
#    $file =~ s!^$tmp_dir/!!;
    if ($file =~ /^\+/) { push @del_files, $file }
    else                { push @ctr_files, $file }
}

or

find sub { push @tmp, $File::Find::name }, $tmp_dir;
#@tmp = map { s!^$tmp_dir/!! } @tmp;
@del_files = grep { /^\+/ } @tmp;

The second one doesn't create @ctr_files (obviously). In both cases you can 
include or leave out the commented line which removes $tmp_dir/ from the 
start of the full pathname, depending whether you want an absolute or 
relative path to the file. (I've used ! as the delimiter in the s/// rather 
than the usual /, because it saves escaping the / on the end of the dirname. 
Remember you can use anything as the delimiter for quote-like operators).

You've called your arrays @del_files and @ctr_files: they will also contain 
directories. One way to eliminate all directories from the lists is to change 
your find line to

find sub {
            my $name = $File::Find::name;
            push @tmp, $name unless $name eq $File::Find::dir;
         }, $tmp_dir;

Jonathan


More information about the Za-pm mailing list