2013-10-03 53 views
0

我有一个Perl脚本,它运行perforce命令并将结果存储在变量$command中。使用Perl执行系统命令

然后它被存储在一个文件log.txt,并通过使用正则表达式相关数据被取出。

当我独自运行该命令下面的事情蹦出:

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 

的代码去如下:

#! /usr/bin/env perl 
use strict; 
use warnings; 
use autodie; 

my $command = qx |p4 monitor show -ale|; 

open FH, '>>', "log.txt"; 
print FH $command; 
close FH; 

open my $log_fh, '<', '/root/log.txt'; 
my %stat; 
while ($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; 

my $killpro; 
foreach my $kill (keys %stat) { 
    print "$kill\n"; 
} 

下得到编号8869,但如何做到这一点没有日志。文本。是使用数组更好的方式来做到这一点或哈希是好的?

请改正我,因为我仍然在学习。

+0

由于您使用的是EOL锚,因此不需要执行两个单独的正则表达式。它可以很简单地组合成'/ R \ s +集成。* IDLE \ s + none $ /',即使它只有一行,我也会使用'/ R [^ \ S \ n] +集成。* IDLE [^\ S \ n] +无$ /'确定。 – sln

回答

1

似乎你的主要绊脚石是为你的循环逐行输入?

拆分对换行应该做的伎俩:

my $killid; 
my @lines = split("\n", $command); #split on newlines 
for my $line (@lines) { 
    next if not $line =~ /(\d+)\s+/; 
    my $id = $1; 
    if ($line =~ /R\s+integration/ and $line =~ /IDLE\s+none$/){ 
     $killid = $id; 
    } 
} 

警告:你提到的8870的输出,但我发现了8869.你给正在寻找与“整合”线路的正则表达式和“IDLE none”,以及看起来与8869匹配的示例输入。

散列很好,但如果您只使用一个键(似乎是这种情况),那么您可能只是使用单个变量。

+0

我已经编辑了上述问题,你说的对8869是正确的。谢谢你的代码运行良好,并达到目的。另外,你提到了一个散列引用。不同的杀戮者不被视为散列的不同密钥或那个引用是什么。请你详细说明。谢谢。 – deep

+1

@deep:您显示的数据只有一行包含“R integration”和“IDLE none”。如果情况总是如此,则不需要使用散列;一个标量就足够了。但是,如果有时可能有几条这样的线路,那么你确实需要一个散列。 – Borodin

+0

你们俩都在那里。对不起,我的部分疏忽了。 – rutter

1

如果您将qx构造的结果赋值给数组而不是标量,那么它将自动为您分割成几行。此代码演示。

use strict; 
use warnings; 

my @lines = qx|p4 monitor show -ale|; 

my %stat; 
for my $line (@lines) { 
    chomp $line; 
    next unless $line =~ /(\d+)\s+/; 
    my $killid = $1; 
    if ($line =~ /R\s+integration/ and $line =~ /IDLE\s+none$/) { 
    $stat{$killid} = $line; 
    } 
} 

print "$_\n" for keys %stat; 
+0

完美的你在这里清除了我的疑惑。谢谢。 – deep