Thiyagu ATR
Thiyagu ATR

Reputation: 2264

how to read files and its subdirectories files using perl

in Perl i need to read file from a parent directory to it's last file it any sub directory is there i need to read those files too!so I've tried something like this with the help of recursive function but it gives infinite loop so can anybody help me! code;

sub fileProcess{
(my $file_name)=@_;
print "$file_name it is file\n";
}
sub main{
    (my $dir)=@_;
    chdir $dir; 
    my $tmp=`pwd`;
    my @tmp =<*>;
    chomp(@tmp);    
    foreach my $item(@tmp){
        chomp($item);
        if(-d $item){
            dirProcess("$tmp/$item");
        }else{
            fileProcess($item);
        }
    } 
}
sub dirProcess{

    (my $file_name)=@_;

    print ">>the corresponding dir is $file_name<<";    
    main($file_name);

}
my $home="../../Desktop";
chdir $home;
my $path=`pwd`;
main($home);

Upvotes: 0

Views: 1046

Answers (2)

kjprice
kjprice

Reputation: 1318

Here's a sub that will search recursively :

sub find_files {
    my ($dir) = @_;
    my (@files, @dirs) = ();
    my (@allfiles, @alldirs) = ();

    opendir my $dir_handle, $dir or die $!;
    while( defined( my $ent = readdir $dir_handle ) ) {
        next if $ent =~ /^\.\.?$/;

        if( -f "$dir/$ent" ) {
            push @files, "$dir/$ent";
        } elsif( -d "$dir/$ent" ) {
            push @dirs, "$dir/$ent";
        }
    }
    close $dir_handle;

    push @allfiles, @{ process_files($_) } for @files;
    push @alldirs, @{ find_files($_) } for @dirs;

    return \@alldirs;
}

Upvotes: 1

Borodin
Borodin

Reputation: 126722

The main reason your code isn't working is that, when dirProcess it calls main again which does chdir to a different directory. That means the rest of the files in the @tmp array aren't found.

To fix it I have just added a chdir $dir after the call to dirProcess. In addition I have

  • Added use strict and use warnings. Yyou must always put these at the top of your program.

  • Removed all calls to pwd which were unnecessary. You know what you present working directory is because you've just set it!

  • Removed unnecessary chomp calls. The information from glob never has trailing newlines. The one string that did need chomping is $tmp but you didn't do it!

It's still not a very nice piece of code, but it works!

use strict;
use warnings;

sub fileProcess {
    (my $file_name) = @_;
    print "$file_name it is file\n";
}

sub main {

    (my $dir) = @_;

    chdir $dir;
    my @tmp = <*>;

    foreach my $item (@tmp) {
        if (-d $item) {
            dirProcess("$dir/$item");
            chdir $dir;
        }
        else {
            fileProcess($item);
        }
    }
}

sub dirProcess {

    (my $file_name) = @_;

    print ">>the corresponding dir is $file_name<<\n";
    main($file_name);
}

my $home = "../../Desktop";

main($home);

Upvotes: 0

Related Questions