2010-12-01 2 views
3

Я хочу архивировать все txt-файлы с помощью File :: Find, удалять исходные файлы и удалять пустые каталоги.Perl Archive :: Tar

У меня возникли трудности с переименованием файлов с помощью $ $ tar-> rename(); ' потому что я хотел бы удалить их из их полных имен путей и использовать только родительский каталог/*. txt, но все, что я пытаюсь переписать, переименовывает только один файл.
Я не знаю, где подходящее место для выполнения функции «unlink».

Спасибо.

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

Вы используете интерфейс «Файл :: Найти» неправильно. Архив sub получает вызов один раз на каждый найденный файл. В конечном итоге вы создаете новый tar для каждого вызова, добавляя к нему один файл и записывая его.

Исправление: Вы в конечном итоге пытаетесь добавить все найденные ранее файлы, но вы уже отсоединили все, кроме последнего.

Давайте делать это небольшими шагами - сначала найти и классифицировать все .txt файлы в соответствии с каталога, а затем добавить их в соответствующие файлы дегтя, и, наконец, очистить:

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

Смежные вопросы