【问题标题】:Perl Archive::TarPerl 存档::Tar
【发布时间】:2010-12-01 11:54:21
【问题描述】:

我想用 File::Find 归档所有 txt 文件,删除源文件并删除空目录。

我在使用 '$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},'.');
}

【问题讨论】:

    标签: perl


    【解决方案1】:

    您错误地使用了 File::Find 界面。 archive 子会在找到的每个文件上调用一次。您最终会在每次调用时创建一个新的 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;
    

    【讨论】:

    • 很好的解决方案。这正是我一直在寻找的。无限感谢。
    • 确实,很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 2020-04-04
    • 2017-03-30
    • 2012-07-21
    • 2014-02-03
    • 2016-10-08
    • 2016-11-27
    相关资源
    最近更新 更多