2010-12-01 11 views
3

File :: Findですべてのtxtファイルをアーカイブして、ソースファイルを削除して空のディレクトリを削除します。Perl Archive :: 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インターフェイスを誤って使用しています。 アーカイブ subは、見つかったファイルごとに1回呼び出されます。すべての呼び出しで新しいタールを作成し、1つのファイルを追加して書き出します。

修正:最後に見つかったファイルをすべて追加しようとしましたが、最後のファイル以外はすべてリンク解除済みです。

のは、小さなステップでこれをやってみましょう - 最初のディレクトリに応じてすべての.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

+0

確かに、非常に役に立ちます。 – taiko

関連する問題