Arrays 数组的perl散列问题

Arrays 数组的perl散列问题,arrays,perl,hash,Arrays,Perl,Hash,我的数组中有几行@lines,其中*向我显示命令的开始时间(如sync/fetch),具有相同processIDpid的行和不带*的命令向我显示结束时间。它们可能并不总是连续的。我想获取特定processID和cmd的startdate和enddate。与usera一样,带有processID11859的cmdsync从2015/01/13 13:53:01.491-05:00开始,在2015/01/13:55:01.492-05:00结束 下面是我的方法,我使用数组的散列并使用processI

我的数组中有几行
@lines
,其中
*
向我显示命令的开始时间(如sync/fetch),具有相同processID
pid
的行和不带
*
的命令向我显示结束时间。它们可能并不总是连续的。我想获取特定
processID
cmd
startdate
enddate
。与
usera
一样,带有processID
11859
的cmd
sync
2015/01/13 13:53:01.491-05:00开始,在
2015/01/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 ];

    }
@行中的内容

2015/01/13 13:53:01.491-05:00 11859 usera       *sync_cmd 7f1f9bfff700 10.101.17.111      
2015/01/13 13:57:02.079-05:00 11863 userb       *fetch_cmd 7f1f9bfff700 10.101.17.111
2015/01/13 13:59:02.079-05:00 11863 userb       fetch_cmd 7f1f9bfff700 10.101.17.111
2015/01/13 13:55:01.492-05:00 11859 usera       sync_cmd 7f1f9bfff700 10.101.17.111 

当您分配给
%用户{$pid}
时,您假定最近的
$startdate
$enddate
都是相关的。保存字段值的变量的作用域大于
foreach
循环,从而允许这些值在记录之间溢出,这一事实加剧了这个问题

if
块中,应将
$startdate$user$cmd的值分配给数组。单独或作为一片,如果你喜欢。在
else
块中,您应该将
$enddate
分配给它在数组中的元素


Regex额外积分:您似乎并不真正关心记录中是否有多个
*
,这使得Regex中的
+
多余。作为额外的奖励,没有它,捕获组也没有任何价值
m{\*}
应该做得很好。

当您分配给
%用户{$pid}
时,您假定最近的
$startdate
$enddate
都是相关的。保存字段值的变量的作用域大于
foreach
循环,从而允许这些值在记录之间溢出,这一事实加剧了这个问题

if
块中,应将
$startdate$user$cmd的值分配给数组。单独或作为一片,如果你喜欢。在
else
块中,您应该将
$enddate
分配给它在数组中的元素


Regex额外积分:您似乎并不真正关心记录中是否有多个
*
,这使得Regex中的
+
多余。作为额外的奖励,没有它,捕获组也没有任何价值
m{\*}
应该做得很好。

当您分配给
%用户{$pid}
时,您假定最近的
$startdate
$enddate
都是相关的。保存字段值的变量的作用域大于
foreach
循环,从而允许这些值在记录之间溢出,这一事实加剧了这个问题

if
块中,应将
$startdate$user$cmd的值分配给数组。单独或作为一片,如果你喜欢。在
else
块中,您应该将
$enddate
分配给它在数组中的元素


Regex额外积分:您似乎并不真正关心记录中是否有多个
*
,这使得Regex中的
+
多余。作为额外的奖励,没有它,捕获组也没有任何价值
m{\*}
应该做得很好。

当您分配给
%用户{$pid}
时,您假定最近的
$startdate
$enddate
都是相关的。保存字段值的变量的作用域大于
foreach
循环,从而允许这些值在记录之间溢出,这一事实加剧了这个问题

if
块中,应将
$startdate$user$cmd的值分配给数组。单独或作为一片,如果你喜欢。在
else
块中,您应该将
$enddate
分配给它在数组中的元素


Regex额外积分:您似乎并不真正关心记录中是否有多个
*
,这使得Regex中的
+
多余。作为额外的奖励,没有它,捕获组也没有任何价值
m{\*}
应该做得很好。

我正在查看您的代码,想知道为什么要使用数组散列

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

你是否可以不这样做:

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";
        }
    }
}

您可能需要一些额外的验证测试,以防您有足够长的日志可以重用PID,或者您有一个不包括特定流程的开始和结束的日志

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

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

你是否可以不这样做:

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";
        }
    }
}

您可能需要一些额外的验证测试,以防您有足够长的日志可以重用PID,或者您有一个不包括特定流程的开始和结束的日志

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

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

你是否可以不这样做:

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";
        }
    }
}

您可能需要一些额外的验证测试,以防您有足够长的日志可以重用PID,或者您有一个不包括特定流程的开始和结束的日志

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

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

你是否可以不这样做:

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";
        }
    }
}