用perl来实现删除文件夹下所有文件(夹)的操作

首先说明一下实现的功能:(Linux环境)指定一个路径,将该路径下的所有文件或者文件夹进行删除。
为了简单起见,这里指定的路径为全路径,不能使用相对路径。对于如何获取全路径实现方式有很多,这里不再 介绍。
本文主要分为以下几个部分
1)获取目录下文件的方法
2)为什么不能使用rm -rf的方式
3)perl的代码实现

获取目录下文件的方法

在提供解决方法之前,首先介绍一下perl来获取目录下文件方法。
方法一:使用句柄的方式

my $dir_name = "/home/usrer/documents";
opendir(DIR, $dir_name) || die "Can't open directory $dir_name"; 
my @dots = readdir(DIR); 
foreach (@dots){ 
        print; 
        print "/n"; 
} 
closedir DIR; 

–这种方法得到的是相对路径下的文件名。如果需要对文件进行深入处理,比如读取文件内容等操作,还需要组合获取全路径。

方法二: 使用glob操作

my @files=glob("/home/usrer/documents/*"); 
foreach (@files) {
    print;
    print "\n";
}

–glob所获得获取目录中的所有文件(以及文件夹)并按字母顺序排序,但不包括以点号开头的文件。也就是说这种方法并不能获取隐藏文件。
–这种方式获得的文件或者文件夹是全路径文件和目录名,通常进行下不需要再进行组合获取全路径,可以直接进行其它处理

为什么不能使用rm -rf的方式

有人提出为什么不能使用system(“rm -rf dir_name”);的方式来实现?这样岂不是很简单?
对于手动方式进行处理,使用rm -rf方式的确很方便,但是在脚本中使用这种方式需要保证$dir_name为期望的值,不能是根目录“/”或者其它目录。在脚本处理中如何判断目录的有效性并不是一个简单的事情。期望的路径为“a/b/c”,怎么判断路径不是a或者a/b,甚至是a/c?在复制的情况下这种判断方式也不一定通用。
我们认为使用rm -rf方式的操作不是安全的。

perl的代码实现

代码实现如下


use strict;
use warnings;

use autodie;
use File::Spec;

my $log_file = File::Spec->catfile("/home/operation", "logs/recover_operation.log");
open(LOG_FILENAME, '>', "$log_file");
my $target_directory = "/tmp";
&delete_all_files_under_path($target_directory);
close LOG_FILENAME;
exit 0;

sub delete_all_files_under_path {
    (my $file_path) = @_;
    print LOG_FILENAME "delete all files and directories under path $file_path\n";
    opendir(DIR, $file_path) or die "Couldn't open $file_path. Reasion : $!\n";
    while (1) {
        my @all_files = readdir(DIR);
        my $length = @all_files;
        # print "file number is : $length under $file_path\n";
        if ( $length == 0 ) {
            last;
        }
        foreach my $file(@all_files) {
            # print "current file is : $file\n";
            if ( ($file eq ".") || ($file eq "..") ) {
                next;
            }
            my $tmp = File::Spec->catfile($file_path,$file);
            # print "deal with current file $tmp\n";
            if ( -d $tmp ) {
                # print "--delete directory $tmp begin\n";
                &delete_directory($tmp);
                # print "--delete directory $tmp finished\n";
                redo;
            } elsif ( -f $tmp) {
                unlink "$tmp";
                # print "--delet file $tmp finished\n";
            }
        }
    }
}

sub delete_directories_under_path {
    (my $file_path) = @_;
    print LOG_FILENAME "delete all directories under path $file_path\n";
    opendir(DIR, $file_path) or die "Couldn't open $file_path. Reasion : $!\n";
    while (1) {
        my @all_files = readdir(DIR);
        my $length = @all_files;
        # print "file number is : $length under $file_path\n";
        if ( $length == 0 ) {
            last;
        }
        foreach my $file(@all_files) {
            # print "current file is : $file\n";
            if ( ($file eq ".") || ($file eq "..") ) {
                next;
            }
            my $tmp = File::Spec->catfile($file_path,$file);
            # print "deal with current file $tmp\n";
            if ( -d $tmp ) {
                # print "--delete directory $tmp begin\n";
                &delete_directory($tmp);
                # print "--delete directory $tmp finished\n";
                redo;
            }
        }
    }
}

sub delete_directory {
    (my $file_path) = @_;
    # print "again delete all file under $file_path\n";
    opendir(DIR, $file_path) or die "Couldn't open $file_path. Reasion : $!\n";
    while (1) {
        my @all_files = readdir(DIR);
        my $length = @all_files;
        # print "file number is : $length under $file_path\n";
        if ($length eq 0 ) {
            rmdir $file_path;
            last;
        }
        foreach my $file (@all_files) {
            # print "again current file is : $file\n";
            if ( ($file eq ".") || ($file eq "..") ) {
                next;
            }
            my $tmp = File::Spec->catfile($file_path,$file);
            # print "again deal with current file $tmp\n";
            if ( -d $tmp ) {
                &delete_directory($tmp);
                # print "again --delete directory $tmp finished\n";
                redo;
            } elsif ( -f $tmp) {
                unlink "$tmp";
                # print "again --delete file $tmp over\n";
            }
        }
    }
    closedir(DIR);
}

对于上述脚本中的不足之处,请大家交流,多多指正,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值