更有效的正则表达式解析Linux顶级命令值



我试图在我正在编写的这个脚本中获取每个进程级别的一些测量值。查看我正在寻找的值的最简单方法是获取top命令的输出。

所以当我尝试解析它时,我的正则表达式看起来有点可笑。给定这个输出:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 8364 cgroup_t  20   0  764m 646m 1520 R 101.7  4.3   0:05.51 perl

我想出了一个正则表达式来获取一些值(8364被传递到一个var上,为了便于阅读,在这里显示,顶部输出存储在一个名为$top_string的var上):

if($top_string =~ m/^s*8364s+([^s]+)s+([^s]+)s+([^s]+)s+([^s]+)s+([^s]+)s+([^s]+)s+([^s]+)s+([^s]+)s+([^s]+)s+([^s]+)s+([^s]+)/){
    #return desired var number, ie.  $1,$2...etc
}

这是有效的,但似乎有点过头了。有什么办法能更有效地做到这一点吗?我觉得我可能记得一种避免反复输入s+([^s]+)模式的方法。

无论如何,感谢你花时间阅读这篇文章!

欢呼

使用分隔符

my @cols = split ' ', ( $top_string =~ /(d.+)/ )[0];

我不知道您是否受到Perl的限制,或者只是为此编写了一个简单的脚本。在第二种情况下,您可以使用awk,在这种情况下,它是直接的:

{
    if ($1 == <process_value_here>)
    {
        print $1 /* Pid*/ "," $2 /*user*/ ...
    }
}

awk默认情况下通过空格分割输入,因此您可以直接访问$x, x是字段的编号。

正如已经说过的,只使用split。但是,一个技巧是将列数限制为12,因为top命令中的最后一列可以包含空格。

use strict;
use warnings;
my $top_string = do { local $/; <DATA> };
for my $line (split "n", $top_string) {
    my @cols = split ' ', $line, 12;
    print "@colsn" if $cols[0] =~ /^8364$/;
}
__DATA__
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 8364 cgroup_t  20   0  764m 646m 1520 R 101.7  4.3   0:05.51 perl

认为这是一个有点天真的回答,但这是我最讨厌的事情。我看到很多Linux上的人想要获得关于他们程序中特定PID的信息,而忽略了/proc目录的存在。当然,它就是为这种事情而创建的(以编程方式提取有关特定进程的信息)。

为了从'Top'中获取信息,你需要调用外部程序,这需要一个分支和所有后续代码来管理该分支-也许在Perl中很容易,但我习惯了C,在C中这是更多的开销,然后我想处理。然后,您必须编写一个正则表达式(将引号"现在您有两个问题"排队)来解析输出。

直接从/proc/条目中读取只需要标准的文件IO,并且/proc的输出被设计为以编程方式解析,因此不需要复杂的RExp来处理它。

Linux上的

Top从/proc内部读取它的信息——所以我找不到一个不去掉中间人的好理由。我唯一能想到的是可移植性,因为一些* nix没有/proc目录。但是Top输出的可移植性(BSD Top和GNU Top可能有细微的不同)。

最新更新