rodnower
rodnower

Reputation: 1405

How to determinate file in Perl

I use File::Find -> find(\&f, $directory) for find some file with some content. Relevant part of my delegate looks like:

sub f {
  my $file = $File::Find::name;
  return unless -f $file;
  return unless $file =~ /$file_pattern/;

  etc...

but the problem is that, that this code returns every time where $file not exist in current directory. For example for file ./test it fine, but for file ./dir/test this return...

Is there some better way to know if $file is file?

Upvotes: 1

Views: 278

Answers (3)

rodnower
rodnower

Reputation: 1405

Thank you all for replays, but you are wrong :) Here is some bug. It work only with full path. I perform some test. Here is the code:

#!/usr/bin/perl

use strict;
use File::Find;
use Cwd;

print "++ With relative path ++\n";
find(\&f, ".");

print "\n++ With current working directory module ++\n";
find(\&f, cwd);

sub f
{
        my $file = $File::Find::name;
        print $file . ":\n";

        if (-f $file) { print "---- ist Datai\n"; }
        else { print "---- ist nicht eine Datei!!!\n"; }
}

Here are the commands:

[andrey@andreys-comp testdir]$ ls -l innerdir/
total 4
-rw-rw-r-- 1 andrey andrey 0 Jun 18 22:02 innertestfile
[andrey@andreys-comp testdir]$ ./test.pl
++ With relative path ++
.:
---- ist nicht eine Datei!!!
./test.pl:
---- ist Datai
./testfile:
---- ist Datai
./innerdir:
---- ist nicht eine Datei!!!
./innerdir/innertestfile:
---- ist nicht eine Datei!!!

++ With current working directory module ++
/home/andrey/testdir:
---- ist nicht eine Datei!!!
/home/andrey/testdir/test.pl:
---- ist Datai
/home/andrey/testdir/testfile:
---- ist Datai
/home/andrey/testdir/innerdir:
---- ist nicht eine Datei!!!
/home/andrey/testdir/innerdir/innertestfile:
---- ist Datai

ist Datei: is file
ist nicht eine Datei: is not file (I just like German :) )

Put your attension that in first method ./innerdir/innertestfile not determined as file, rather than in second.

Upvotes: -1

modz0r
modz0r

Reputation: 1062

How about checking with

if (! -f $file) { 
   die "not a file";
}

Upvotes: 0

Ed Guiness
Ed Guiness

Reputation: 35277

This line

return unless -f $file;

will return if $file is not a file (it could be a folder)

This line

return unless $file =~ /$file_pattern/;

will return if the file name does not contain $file_pattern.

Note that this sub f() does NOT tell File::Find which files to find, according to the documentation...

The wanted() function does whatever verifications you want on each file and directory. Note that despite its name, the wanted() function is a generic callback function, and does not tell File::Find if a file is "wanted" or not. In fact, its return value is ignored.

To find all files in a folder you may find it easier to use File::Find::Rule. Here is an example from the docs...

  my @files = File::Find::Rule->file()
                              ->name( '*.pm' )
                              ->in( @INC );

Upvotes: 7

Related Questions