0

我的 SGEqstat命令输出如下所示: http ://dpaste.com/1177012/plain/

它是通过以下命令获得的:

 $ 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.          
4

1 回答 1

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散列设置为您想要的任何值,或者跳过构建它并只处理 arrayref:

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

关于您的编辑尝试:基本想法非常合理,但是您犯了一些错误(小错误:==而不是=~匹配时/^=/;更重要的错误:将您的哈希键从 = 的行中删除,这对于每个记录,结果您最终只转储了最后一条记录)并且您错过了一些技巧:您存储未处理的记录行而不是将它们分解为键和值。

这个改动展示了:将散列推到一个数组上,并且只为一些键拆分行:

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

于 2013-05-18T04:03:16.833 回答