How can I use File::Find to print files with the relative path only?

4.7k Views Asked by At

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?

2

There are 2 best solutions below

0
Inshallah On BEST ANSWER

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;
5
AudioBubble On

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.