2013-10-03 58 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