1

我有一个如下所示的日志文件:

4680 p4exp/v68     PJIANG-015394 25:34:19 IDLE none
8869 unnamed p4-python       R integration semiconductor-project-trunktip-turbolinuxclient 01:33:52 IDLE none
8870 unnamed p4-python       R integration remote-trunktip-osxclient 01:33:52 

在同一个日志文件中有许多这样的条目,因此有些条目最后不包含 IDLE none,而有些则不包含。我想在哈希中保留具有“R 集成”和“IDLE none”的那些并忽略其余部分。我尝试了以下代码,但没有得到想要的结果。

#!/usr/bin/perl
open (FH,'/root/log.txt');
my %stat;
my ($killid, $killid_details);
while ($line = <FH>) {
    if ($line =~ m/(\d+)/){
            $killid = $1;
    }
    if ($line =~ /R integration/ and $line =~ /IDLE none/){
            $killid_details = $line;
    }
    $stat{$killid} = {
            killid => $killid_details
    };
}
close (FH);

我得到了 R 集成的所有行(例如,我得到 8869、8870 行),这不应该是因为 8870 应该被忽略。

如果有任何错误,请告诉我。我还在学习perl。谢谢你。

4

2 回答 2

5

我对您的程序进行了一些更改:

  • 始终输入use strict;use warnings;。这些将捕获您 90% 的错误。(虽然这次不是)。
  • 打开文件时,您需要使用or dieas inopen my $fh, "<", $file or die qq(blah, blah, blah);或使用use autodie;(现在首选)。在您的情况下,如果文件没有打开,您的程序将继续愉快地进行。您需要测试该open语句是否有效。
  • 注意我的open说法。我使用一个变量作为文件句柄。这是首选,因为它不是全局的,并且更容易传递到子例程中。另请注意,我使用了三个参数open。这样,如果您的文件名以某个奇怪的字符开头,您就不会遇到麻烦。
  • 声明变量时,最好在范围内进行。这样,当您不再需要变量时,它们就会超出范围。我移动了在循环内声明的位置$killid和位置。$killid_details这样,它们就不再存在于循环之外。
  • 你需要更加小心你的正则表达式。如果该短语IDLE none出现在您的行中的其他地方怎么办?你只想要它,如果它在行尾。

现在,对于您遇到的问题:

  • 当你阅读它们时,你需要chomp划线。在 Perl 中,读入行尾的 NL。该chomp命令将其删除。
  • 你的逻辑有点奇怪。您设置$killid您的行中是否有数字(我将其修改为仅查找行首的数字)。但是,即使killid没有设置,您也只是在快乐地前进。在您的版本中,因为您$killid在循环之外声明,所以它在每个循环中都有一个值。$killid在这里,如果未定义,我将转到下一个语句。
  • 您对哈希的定义很奇怪。您正在散列中定义参考散列。没必要。我把它做成了一个简单的哈希。

这里是:

#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use autodie;
use Data::Dumper;

open my $log_fh, '<', '/root/log.txt';

my %stat;
while (my $line = <$log_fh>) {
    chomp $line;
    next if not $line =~ /^(\d+)\s+/;
    my $killid = $1;
    if ($line =~ /R\s+integration/ and $line =~ /IDLE\s+none$/){
        my $killid_details = $line;
        $stat{$killid} = $killid_details;
    }
}
close $log_fh;

say Dumper \%stat;
于 2013-10-02T19:47:33.407 回答
1

我想这可能是你想要的:

while (<FH>) {
    next unless /^(\d+).*R integration.*IDLE none/;
    $stat{$1} = $_;
}

正则表达式应锚定到行首,因此您不会匹配行中任何位置的数字。R integration假设和的顺序IDLE none始终如示例中所示,则无需进行多个正则表达式匹配。你需要在next没有匹配的时候使用,所以你不会处理不匹配的行。

而且我怀疑您只想将哈希条目的值设置为字符串,而不是对另一个哈希的引用。

于 2013-10-02T19:42:45.747 回答