2010-12-01 4 views
3

File :: Find로 모든 txt 파일을 보관하고 원본 파일을 삭제하고 빈 디렉토리를 제거하고 싶습니다.Perl 아카이브 :: 타르

'$ 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는 발견 된 모든 파일에서 한 번 호출됩니다. 모든 호출에 대해 새 타르 (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

다양한 솔루션을 : 첫번째 관련 tar 파일에 추가 한 후, 찾아 디렉토리에 따라 모든 .txt 인 파일을 분류하고, 마지막으로 정리 -

이의 작은 단계에서이 작업을 수행하자. 그게 바로 제가 찾고 있던 것입니다. 무제한 감사. – thebourneid

+0

참으로 도움이됩니다. – taiko