Question

I am using Perl. I am making an array of files inside a directory. Hidden files, ones that begin with a dot, are at the beginning of my array. I want to actually ignore and skip over those, since I do not need them in the array. These are not the files I am looking for.

The solution to the problem seems easy. Just use regular expression to search for and exclude hidden files. Here's my code:

opendir(DIR, $ARGV[0]);                             
my @files = (readdir(DIR)); 
closedir(DIR);  

print scalar @files."\n"; # used just to help check on how long the array is



for ( my $i = 0; $i < @files; $i++ )
    {
     # ^ as an anchor, \. for literal . and second . for match any following character

     if ( $files[ $i ] =~ m/^\../ || $files[ $i ] eq '.' ) #
        {
         print "$files[ $i ] is a hidden file\n";

         print scalar @files."\n";  
        }

    else
       {
         print $files[ $i ] . "\n";
       }

    } # end of for loop

This produces an array @files and shows me the hidden files I have in the directory. Next step is to remove the hidden files from the array @files. So use the shift function, like this:

opendir(DIR, $ARGV[0]);                             
my @files = (readdir(DIR)); 
closedir(DIR);  

print scalar @files."\n"; # used to just to help check on how long the array is



for ( my $i = 0; $i < @files; $i++ )
    {
     # ^ as an anchor, \. for literal . and second . for match any following character

     if ( $files[ $i ] =~ m/^\../ || $files[ $i ] eq '.' ) #
        {
         print "$files[ $i ] is a hidden file\n";
         shift @files;
         print scalar @files."\n";  
        }

    else
       {
         print $files[ $i ] . "\n";
       }

    } # end of for loop

I get an unexpected result. My expectation is that the script will:

  1. make the array @files,
  2. scan through that array looking for files that begin with a dot,
  3. find a hidden file, tell me it found one, then promptly shift it off the front end of the array @files,
  4. then report to me the size or length of @files,
  5. otherwise, just print the name of the files that I am actually interested in using.

The first script works fine. The second version of the script, the one using the shift function to remove hidden files from @files, does find the first hidden file (. or current directory) and shifts it off. It does not report back to me about .., the parent directory. It also does not find another hidden file that is currently in my directory to test things out. That hidden file is a .DS_store file. But on the other had, it does find a hidden .swp file and shifts it out.

I can't account for this. Why does the script work OK for the current directory . but not the parental directory ..? And also, why does the script work OK for a hidden .swp file but not the hidden .DS_Store file?

Was it helpful?

Solution

After shifting a file, your index $i now points to the following file.

You can use grep to get rid of the files whose names start with a dot, no shifting needed:

my @files = grep ! /^\./, readdir DIR;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top