2013-05-18 40 views
0

的輸出我從SGE qstat命令看起來像這樣的輸出: http://dpaste.com/1177012/plain/解析SGE的(qstat命令-j「*」)使用AWK或Perl

它與下面的命令獲得:

$ qstat -j "*" 

我想要做的是分析的qstat命令-j輸出「*」 成表格格式:

#job_number submission_time owner usage 
526715  Sat Apr 13 18:43:19 2013 yminakuc cpu=33:04:05:52, mem=2471753193.24440 GBs, io=619.41401, vmem=864.175G, maxvmem=920.232G 
.... 

我呈丁邏輯思維能力,以創建可作爲管道代碼:

$ qstat -j "*" | ./mycodeparse.pl 

什麼是做在AWK或Perl的方式? 或者是否有任何可用的unix工具?

我堅持用下面的結構(邏輯)

#!/usr/bin/perl -w   
    use strict;     
    use Data::Dumper;   

    my %hash;     
    my $curr; 

    while (my $line = <>) { 
     chomp $line;    


     if ($line == /^=/) { 
      $hash{$line}=$curr = []; 
     } 
     elsif ($line =~ /^job_number/ || 
       $line =~ /^owner/ || 
       $line =~ /^usage/ || 
       $line =~ /^submission_time/)) { 
      push @$curr,$line; 
     } 

    } 

    print Dumper \%hash ; 
    # Hash print everything instead of selected lines.   
+0

沒有工具可以自動完成。 Perl或awk腳本是完美的解決方案。我希望你期待着我們爲你寫信。 – Barmar

+2

你不能使用'qstat -xml'和一個XML解析器嗎? – GWW

回答

1

該格式是相當接近YAML,這樣一個選擇是縮小差距:

perl -lne 'BEGIN { print "---" } if (/^=/) { $new = 1; next } if ($new) { s/^/- /; $new = 0 } else { s/^//} print' paste > paste.yml 

,然後加載它通常情況下:

#! /usr/bin/env perl 
use common::sense; 
use YAML 'LoadFile'; 

die "usage: $0 <file.yml>\n" unless @ARGV == 1; 

my %jobs = map { $_->{job_number}, $_ } @{LoadFile(shift)}; 

say "#job_number submission_time owner usage"; 
for (keys %jobs) { 
    say join("\t", $_, @{$jobs{$_}}{"submission_time", "owner", "usage 1"}) 
} 

由於該醜惡的"usage 1"建議你可能也想按摩按鍵。 names_with_underlines與'帶空格的名字'關鍵字也有所不同。當然,你可以鍵入你想要的任何值%jobs哈希值,否則跳過編譯它,只是處理數組引用:

for (@{LoadFile(shift)}) { 
    say join("\t", @{$_}{"job_number", "submission_time", "owner", "usage 1"}) 
} 

輸出:

#job_number submission_time owner usage 
5276175 Sat Apr 13 18:43:19 2013 yminakuc cpu=33:04:05:52, mem=2471753193.24440 GBs, io=619.41401, vmem=864.175G, maxvmem=920.232G 
606837 Fri Dec 14 19:20:55 2012 ataiba 
6252671 Wed May 8 23:08:22 2013 harukao cpu=9:13:06:40, mem=13115128.89679 GBs, io=19.38717, vmem=16.202G, maxvmem=19.131G 

關於你的編輯,在嘗試:基本想法非常合理,但是你犯了一些錯誤(瑣碎的錯誤:==而不是=~匹配/^=/;更重要的錯誤:將你的散列鍵入=的行,這對每條記錄都是一樣的,結果你只會傾倒最後一張唱片),並且你錯過了一些小技巧:f.e.您存儲未處理的記錄行,而不是將它們分解爲鍵和值。

這種改變表明:推哈希值到一個數組,分割線只有一些按鍵:傾銷輸出

if ($line =~ /^=/) { 
    push @array, $curr = {}; 
} 
elsif ($line =~/^ (job_number 
        | owner 
        | usage 
        | submission_time) 
       .*?: \s* (.+)/x) { 
    $curr->{$1} = $2 
} 

摘錄:

{ 
    'usage' => 'cpu=33:04:05:52, mem=2471753193.24440 GBs, io=619.41401, vmem=864.175G, maxvmem=920.232G', 
    'owner' => 'yminakuc', 
    'job_number' => '5276175', 
    'submission_time' => 'Sat Apr 13 18:43:19 2013' 
}, 

一個小的改變你可以用$curr存儲到%hash中,然後用盡你的輸入或運行到另一個====行。