数组的perl哈希问题

时间:2015-01-22 15:51:30

标签: arrays perl hash

我的数组@lines中有几行,其中*显示命令的开始时间(如sync / fetch)和具有相同processID pid的行和命令没有*显示结束时间。它们可能永远不会连续。我想获得特定startdateenddate的{​​{1}}和processID。与cmd一样,processid usera的cmd sync始于11859,结束于2015/01/13 13:53:01.491-05:00

下面是我采用数组哈希并使用2015/01/13 13:55:01.492-05:00作为键的方法,然后分割线。只有当命令的开始和结束行是连续的时,这才能正常工作,但即使它们不连续,我怎样才能使它工作。

processID

my %users; foreach my $line (@lines) { if ($line =~ m{(\*)+}) { ($stdate, $sttime, $pid, $user, $cmd) = split ' ', $line; $startdate ="$stdate $sttime"; } else { ($eddate, $edtime, $pid, $user, $cmd) = split ' ', $line; $enddate = "$eddate $edtime"; } $users{$pid} = [ $startdate, $enddate, $user, $cmd ]; } 中的内容:

@lines

2 个答案:

答案 0 :(得分:2)

我正在查看您的代码,并想知道为什么要使用数组哈希。

就我而言,数组的目的是一组相似但有序的值。

你不能这样做:

my %processes;

foreach (@lines) {
    my ( $date, $time, $pid, $user, $cmd, @everything_else ) = split;

    if ( $cmd =~ m/^\*/ ) {

        #if command starts with a * - it started.
        if ( defined $processes{$pid} ) {
            print "WARNING: $pid reused\n";
        }

        $processes{$pid}{'start_date'} = $date;
        $processes{$pid}{'time'}       = $time;
        $processes{$pid}{'user'}       = $user;
        $processes{$pid}{'cmd'}        = $cmd;
    }
    else {
        #cmd does not start with '*'.
        if ( $processes{$pid}{'cmd'} =~ m/$cmd/ ) {

            #this works, because 'some_command' is a substring of '*some_command'.
            $processes{$pid}{'end_date'} = $date;
            $processes{$pid}{'end_time'} = $time;
        }
        else {
            print
                "WARNING: $pid has a command of $cmd, where it started with $processes{$pid}{'cmd'}\n";
        }
    }
}

您可能需要进行一些额外的验证测试,以防万一一个足够长的日志,pids可以重复使用,或者例如你有一个不包括特定进程的开始和结束的日志。

答案 1 :(得分:1)

当您分配到%users{$pid}时,您认为最近的$startdate$enddate都是相关的。保存字段值的变量的范围大于foreach循环,允许这些值在记录之间出血,这个问题更加严重。

if块中,您应该将$startdate, $user, $cmd的值分配给数组。如果你愿意,可以单独或作为切片。在else块中,您应该将$enddate分配给数组中的元素。

正则表达式额外功劳:你似乎并不在乎记录中是否有更多*,这使得正则表达式中的+变得多余。作为额外的奖励,没有它,捕获组也没有价值。 m{\*}应该做得很好。