Perl解析脚本问题

时间:2014-10-12 19:44:22

标签: perl parsing text

要解析的示例文本文件:

DEG01297D    Up  Wed Oct  1 00:49:13 2014
DEG02522D    Up  Wed Oct  1 00:50:46 2014
DEG01297D    Down    Wed Oct  1 00:54:14 2014
DEG02522D    Down    Wed Oct  1 00:55:20 2014

欲望

SITEID  STATE   DATE    TIME    STATE   DATE    TIME    UP TIME 
DEG01297D    Up Wed Oct  1  0:49:13  Down   Wed Oct  1  0:54:14 0:05:01
DEG02522D    Up Wed Oct  1  0:50:46  Down   Wed Oct  1  0:55:20 0:04:34

代码:

$infile='Test';
$outfile='asqf.txt';
open(INPUT, $infile);
@data = < INPUT >;
close(INPUT);

open(OUTPUT, ">$outfile");
$siteid="";
$status="";
$timeU="";
$timeU="";

for ($i=0; $i <= $#data; ++$i)
{

    @line=split(/\t/,$data[i]);

    if (($line[1] =~ /  Up/))
    {
        $siteid=$line[0];
        print OUTPUT "\n$siteid,";
        $status=$line[1];
        print OUTPUT " $status, ";
        $timeU=$line[2];
        print OUTPUT " $timeU, ";
        $z=$i+1;        

    }

    #for ($x=$z; $x <=$#data; ++$x)
    #{
    #   if (($line[2] =~ /Down/) && ($line[0] == $siteid))
    #   {
    #       $status=$line[2];
    #       print OUTPUT " $status, ";
    #       $timeD=$line[3];
    #       print OUTPUT " $timeD, ";
    #   }
    #   $x=$#data;          
    #}

}

close(OUTPUT);

当前状态

在故障排除期间完成了散列部分。当我在当前演示文稿中运行脚本时,我没有输出。我在第16行做了什么,在第一个for循环中的第一行。

初学者到Perl并且暂时没有编码,任何

2 个答案:

答案 0 :(得分:0)

我认为您应该使用匿名哈希来存储$ data

use strict;
use warnings;
use Date::Parse;

my $data = {};

sub dateDiff{
  my ($d1,$d2) = @_;
  return (str2time($d2) - str2time($d1));
}

open(DATA,"data1.dat") || die $!;
while(my $l = <DATA>){
  chomp($l);
  if($l =~ m/^(\S+)\s+(Up|Down)\s+(.*)$/){
    $data->{$1}->{$2} = $3;
  } else {
    # print the line with errors or log it
  }
}
close(DATA);

print "SITEID\t\tSTATE\tDATE TIME\t\t\tSTATE\t DATE TIME\t\t\tUP\tTIME\n";
foreach my $k1 (keys %{$data}){
  print $k1 . "\t";
  if(defined($data->{$k1}->{"Up"}) && defined($data->{$k1}->{"Down"})){
    print "Up\t" . $data->{$k1}->{"Up"} . "\tDown\t" . $data->{$k1}->{"Down"} 
       . "\tUp\t" . dateDiff($data->{$k1}->{"Up"},$data->{$k1}->{"Down"})."\n";
  }else{
    # print the part line as you need
  }
}

输出以秒为单位,您可以使用任何纪元日期时间方式,以便在需要时以其他格式查看秒数。

答案 1 :(得分:0)

迭代每一行。用先前看到的Up状态绑定状态。最后输出所有结果:

use strict;
use warnings;

use Time::Piece;

my @data = [ qw(SITEID STATE DATE TIME STATE DATE TIME), 'UP TIME' ];
my %siteids;

while (<DATA>) {
    chomp;
    my ( $siteid, $state, $datetime ) = split /\s{4,}/;    # For actual data use /\t/;
    my $tp = Time::Piece->strptime( $datetime, '%a %b %e %T %Y' );

    if ( $state eq 'Up' ) {
        if ( $siteids{$siteid} ) {
            warn "Second Up state found before Down on line $.: $_\n";
        }

        push @data, my $data = [ $siteid, $state, $tp->strftime('%a %b %e'), $tp->strftime('%T') ];

        $siteids{$siteid} = {
            data => $data,
            tp   => $tp,
        };

    } elsif ( $state eq 'Down' ) {
        if ( !$siteids{$siteid} ) {
            warn "Down state found before Up on line $.: $_\n";

        } else {
            my $diff = $tp - $siteids{$siteid}{tp};
            push @{ $siteids{$siteid}{data} }, $state, $tp->strftime('%a %b %e'), $tp->strftime('%T'), $diff->pretty;
            delete $siteids{$siteid};
        }

    } else {
        warn "Unrecognized state on line $.: $_\n";
    }
}

print join( "\t", @$_ ), "\n" for @data;

__DATA__
DEG01297D    Up      Wed Oct  1 00:49:13 2014
DEG02522D    Up      Wed Oct  1 00:50:46 2014
DEG01297D    Down    Wed Oct  1 00:54:13 2014
DEG02522D    Down    Wed Oct  1 00:55:20 2014

输出:

SITEID  STATE   DATE    TIME    STATE   DATE    TIME    UP TIME
DEG01297D   Up  Wed Oct  1  00:49:13    Down    Wed Oct  1  00:54:13    5 minutes, 0 seconds
DEG02522D   Up  Wed Oct  1  00:50:46    Down    Wed Oct  1  00:55:20    4 minutes, 34 seconds