perl - 在 Perl 中,如何过滤目录中的所有日志文件,并提取感兴趣的行?

标签 perl grep

我试图只选择目录中的 .log 文件,然后在这些文件中搜索“未绑定(bind)”一词,并将整行打印到与日志文件同名的新输出文件中(number###.log) 但带有 .txt 扩展名。这是我目前所拥有的:

#!/usr/bin/perl

  use strict;
  use warnings;

  my $path = $ARGV[0];
  my $outpath = $ARGV[1];
  my @files;
  my $files;

  opendir(DIR,$path) or die "$!";
  @files = grep { /\.log$/} readdir(DIR);


  my @out;
  my $out;
  opendir(OUT,$outpath) or die "$!";

  my $line;
  foreach $files (@files) {
  open (FILE, "$files");
  my @line = <FILE>;
  my $regex = Unbound;
  open (OUT, ">>$out");
  print grep {$line =~ /$regex/ } <>;
   } 
  close OUT;
  close FILE;

  closedir(DIR);
  closedir (OUT);

我是初学者,我真的不知道如何用获取的输出创建一个新的文本文件。

最佳答案

我建议改进此代码的几件事:

  • 在循环中声明循环迭代器。 foreach my $file ( @files ) {
  • 使用 3 个参数 open : open ( my $input_fh, "<", $filename );
  • 使用glob而不是 opendir然后grep . foreach my $file ( <$path/*.txt> ) {
  • grep非常适合将事物提取到数组中。你的grep读取整个文件来打印它,这是没有必要的。如果文件很短,则无关紧要。
  • perltidy非常适合重新格式化代码。
  • 您正在将“OUT”打开到一个目录路径(我想?),但这是行不通的。
  • $outpath不是,它是一个文件。您需要做一些不同的事情来输出到不同的文件。 opendir对输出不是真的有效。
  • 因为您正在使用 opendir这实际上是给你文件名——而不是完整路径。所以你可能在错误的地方打开了文件。在路径名前加上 chdir是可能的解决方案。但这就是我喜欢 glob 的原因之一因为它也返回一条路径。

考虑到这一点 - 如何:

#!/usr/bin/perl

use strict;
use warnings;
use File::Basename;

#Extract paths
my $input_path  = $ARGV[0];
my $output_path = $ARGV[1];

#Error if paths are invalid. 
unless (defined $input_path
    and -d $input_path
    and defined $output_path
    and -d $output_path )
{
    die "Usage: $0 <input_path> <output_path>\n";
}

foreach my $filename (<$input_path/*.log>) {

   # extract the 'name' bit of the filename. 
   # be slightly careful with this - it's based 
   # on an assumption which isn't always true. 
   # File::Spec is a more powerful way of accomplishing this.
   # but should grab 'number####' from /path/to/file/number####.log
   my $output_file = basename ( $filename, '.log' );

   #open input and output filehandles. 
   open( my $input_fh, "<", $filename ) or die $!;
   open( my $output_fh, ">", "$output_path/$output_file.txt" ) or die $!;

   print "Processing $filename -> $output_path/$output_file.txt\n";

   #iterate input, extracting into $line
   while ( my $line = <$input_fh> ) {
        #check if $line matches your RE. 
        if ( $line =~ m/Unbound/ ) {
            #write it to output. 
            print {$output_fh} $line;
        }
   }
   #tidy up our filehandles. Although technically, they'll 
   #close automatically because they leave scope
   close($output_fh);
   close($input_fh);
}

关于perl - 在 Perl 中,如何过滤目录中的所有日志文件,并提取感兴趣的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28633468/

相关文章:

linux - 获取 "-("和 ")-"之间的字符串,linux 目录

linux - 将 Whatsapp bash 脚本的输出重定向到交互式文件以实现自动化目的

regex - Perl 匹配输入中的下一个

java - 使用 apache xml rpc 客户端 3.1.3 发送复杂类型

perl - 如何将特定模式与 if 条件匹配

.NET 等价于 Perl 正则表达式

arrays - 2个哈希数组之间的算术运算

linux - 使用 bash 取十进制数的平均值

regex - 如何对所有非 ASCII 字符进行 grep?

linux - grep -o : Keep input line format