2010-12-01 91 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