【问题标题】:Perl combine multiple file contents to single filePerl 将多个文件内容合并到单个文件中
【发布时间】:2019-11-23 12:07:56
【问题描述】:

我有多个日志文件,比如 file1.log file2.log file3.log 等。我想将这些文件内容合并到一个名为 result_file.log 的文件中

有没有 Perl 模块可以做到这一点?

更新:这是我的代码

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use File::Copy;

my @files;

my $dir = "/path/to/directory";

opendir(DIR, $dir) or die $!;

while (my $file = readdir(DIR)) {

    # We only want files
    next unless (-f "$dir/$file");

    # Use a regular expression to find files ending in .log
    next unless ($file =~ m/\.log$/);

    print "$file\n";

    push( @files, $file);
}

closedir(DIR);

print Dumper(\@files);

open my $out_file, ">result_file.log" ;
copy($_, $out_file) foreach ( @files );

exit 0;

你认为这是可行的解决方案吗?

【问题讨论】:

  • 您尝试了什么,遇到了什么问题?请向我们展示您的代码。
  • 哦,你为什么要用 Perl 做这个?对我来说,这听起来像是 cat 命令的工作。
  • @DaveCross 我在问题中添加了脚本。
  • 我很困惑——最后一部分,使用File::Copy::copy ...是这个问题的答案吗?如果是这样,我建议避免将答案中发布的内容添加到问题中——这会让读者感到非常困惑。 (例如:最后一部分很好地解决了您的问题,就目前而言,所以如果您有这个问题,那么为什么要问这个问题?)
  • @vinodk89 我扩展了 File::Copy 答案 - 请参阅有关 'readdir' 排序与glob 的注释,并建议关闭文件。

标签: file perl


【解决方案1】:

CPAN 'File::Copy' 应该可以完成这项工作,您必须自己打开输出文件。

use File::Copy ;
open my $out, ">result.log" ;
copy($_, $out) foreach ('file1.log', 'file2.log', );
close $out ;

更新 1: 根据发布的附加信息来回答,看起来问题是连接(在 Perl 中)文件列表匹配模式(* .log)。下面扩展了上述解决方案以包含额外的逻辑,使用glob,避免readdir 和过滤。

use File::Copy ;

open my $out, ">result.log" ;
copy($_, $out) foreach glob('/path/to/dir/*.log' );
close $out ;

重要提示: * 使用 glob 将按字母顺序排序文件名,而 readdir 不保证任何顺序。 * 输出文件 'result.log' 匹配 '*.log',不应执行当前目录中的代码。

【讨论】:

    【解决方案2】:

    你认为这是可行的解决方案吗?

    恐怕不会。您的代码相当于在提示符下键入这些命令:

    $ cp file1.log result_file.log
    $ cp file2.log result_file.log
    $ cp file3.log result_file.log
    $ ... etc ...
    

    这样做的问题是它会复制每个文件,依次覆盖前一个文件的顶部。因此,您最终会得到列表中最终文件的副本。

    正如我在评论中所说,使用cay 最容易做到这一点 - 根本不需要 Perl。

    $ cat file1.log file2.log file3.log > result_file.log
    

    如果你真的想在 Perl 中做这件事,那么这样的事情会起作用(第一部分和你的很相似)。

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use Data::Dumper;
    
    my @files;
    
    my $dir = "/path/to/directory";
    
    opendir(my $dh, $dir) or die $!;
    
    while (my $file = readdir($dh)) {
    
        # We only want files
        next unless (-f "$dir/$file");
    
        # Use a regular expression to find files ending in .log
        next unless ($file =~ m/\.log$/);
    
        print "$file\n";
    
        push( @files, "$dir/$file");
    }
    
    closedir($dh);
    
    print Dumper(\@files);
    
    open my $out_file, '>', 'result_file.log';
    
    foreach my $fn (@files) {
        open my $in_file, '<', $fn or die "$fn: $!";
        print $out_file while <$fn>);
    }
    

    【讨论】:

    • 感谢@DaveCross 的建议。 cat 看起来不错的选择。但是这些文件是动态的。如何遍历循环以便在 cat 命令中捕获这些文件。
    • @vinodk89: cat somedir/*.log &gt; result_file.log
    猜你喜欢
    • 2020-09-05
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多