5

I am using File::Find in the code below to find the files from /home/user/data path.

use File::Find;

my $path = "/home/user/data";
chdir($path);
my @files;

find(\&d, "$path");

foreach my $file (@files) {
print "$file\n";
}

sub d {
-f and -r and push  @files, $File::Find::name;
}

As I am changing the dir path to the path from where i need to search the files but still it gives me the files with full path. i.e.

/home/user/data/dir1/file1
/home/user/data/dir2/file2
and so on...

but I want the output like

dir1/file1
dir2/file2
and so on...

Can anyone please suggest me the code to find the files and display from current working directory only?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Space
  • 7,049
  • 6
  • 49
  • 68

2 Answers2

13

The following will print the path for all files under $base, relative to $base (not the current directory):

#!/usr/bin/perl
use warnings;
use strict;

use File::Spec;
use File::Find;

# can be absolute or relative (to the current directory)
my $base = '/base/directory';
my @absolute;

find({
    wanted   => sub { push @absolute, $_ if -f and -r },
    no_chdir => 1,
}, $base);

my @relative = map { File::Spec->abs2rel($_, $base) } @absolute;
print $_, "\n" for @relative;
Inshallah
  • 4,804
  • 28
  • 24
3

How about just removing it:

foreach my $file (@files) {
$file =~ s:^\Q$path/::;
print "$file\n";
}

Note: this will actually change the contents of @files.

According to comments this doesn't work, so let's test a full program:

#!/usr/local/bin/perl
use warnings;
use strict;
use File::Find;

my $path = "/usr/share/skel";
chdir($path);
my @files;

find(\&d, "$path");

foreach my $file (@files) {
$file =~ s:^\Q$path/::;
print "$file\n";
}

sub d {
-f and -r and push  @files, $File::Find::name;
}

The output I get is

$ ./find.pl
dot.cshrc
dot.login
dot.login_conf
dot.mailrc
dot.profile
dot.shrc

This seems to be working OK to me. I've also tested it with directories with subdirectories, and there is no problem.

  • Thanks, but Its not working for me. Still getting the full path. – Space Nov 10 '09 at 13:10
  • Yes, I have copied and pasted but its giving the the full path from /. – Space Nov 10 '09 at 13:26
  • I have added the full testing program to the above. If this still does not work, please give your perl version and operating system for further testing. –  Nov 10 '09 at 13:54
  • This is still not working, I am using perl 5.8.8 and OS is Linux. However, if I am using $file =~ s/$path//g; instead of $file =~ s:^\Q$path/::; its working. – Space Nov 10 '09 at 14:00
  • 1
    At least your problem is solved then. I tested this with both perl 5.8.9 and 5.10.0 on FreeBSD, and there is no problem with the regex. –  Nov 10 '09 at 14:06