2010-12-01 74 views
3

我想用File :: Find来存档所有的txt文件,删除源文件并删除空目录。Perl档案:: Tar

我很难用'$ tar-> rename()重命名文件;''因为我想从完整路径名称中删除它们,并只使用父目录/ *。txt,但无论我尝试的代码是否只重命名一个文件。
我不知道执行“取消链接”功能的适当位置在哪里。

谢谢。

use strict; 
use warnings; 
use Archive::Tar; 
use File::Find; 
use File::Basename; 

my $dir = "E:/"; 

my @files =(); 

find(\&archive, $dir);  
sub archive { 
    /\.txt$/ or return; 
    my $fd = $File::Find::dir; 
    my $fn = $File::Find::name; 
    my $folder = basename($fd); 
    my $file = $_; 

    push @files, $fn; 

    my $tar = Archive::Tar->new(); 
    $tar->add_files(@files); 
    $tar->rename($fn, $folder."\\".$file); 
    $tar->write($fd.'.tar'); 

    unlink $fn; 
    finddepth(sub{rmdir},'.'); 
} 

回答

6

您正在错误地使用File :: Find界面。 档案在每个找到的文件上被调用一次。您最终会在每次调用时创建一个新的tar,向其中添加一个文件并将其写出。

纠错:您最终试图添加所有以前找到的文件,但除了最后一个之外,您已经取消了所有链接。

让我们做这个小步骤 - 首先找到并根据目录中的所有.txt文件进行分类,然后将它们添加到相关的tar文件,最后清理:

my $dir = "E:/"; 

my %txt_files =(); 

find(\&classify, $dir);  
sub classify{ 
    /\.txt$/ or return; 
    my $fd = $File::Find::dir; 
    my $fn = $File::Find::name; 

    push @{$txt_files{$fd}||=[]}, $fn; 
} 

foreach my $folder (keys %txt_dirs) { 
    my @files = @{$txt_files{$folder}}; 
    my $foldername = basename($folder); 

    my $tar = Archive::Tar->new(); 
    $tar->add_files(@files); 
    $tar->rename($_, $foldername."/".basename($_)) 
     for @files; 

    $tar->write($folder.'.tar'); 
} 

# remove all the txt files we've found 
unlink for map {@{$_}} values %txt_files; 

# try to remove the directories that contained the txt files 
eval {rmdir} for keys %txt_files; 
+0

的最佳解决方案。这正是我所期待的。无限感谢。 – thebourneid 2010-12-01 04:06:42