我试图在这个脚本的每个进程级别上获取一些测量值。查看我正在寻找的值的最简单方法是只获取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*8364\s+([^\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]+)
模式的方法。
无论如何,感谢您花时间阅读本文!
干杯
答案 0 :(得分:1)
我不知道你是否已经限制在Perl之外,或者只是为此写了一个简单的脚本。在第二种情况下,您可以使用awk
,在这种情况下它是直接的:
{
if ($1 == <process_value_here>)
{
print $1 /* Pid*/ "," $2 /*user*/ ...
}
}
默认情况下, awk
会按空格分割输入,因此您可以直接访问$x
,x
是字段的编号。
答案 1 :(得分:1)
在有分隔符时使用拆分
my @cols = split ' ', ( $top_string =~ /(\d.+)/ )[0];
答案 2 :(得分:1)
如前所述,只需使用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 "@cols\n" 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
答案 3 :(得分:0)
认为这是一个有些温和的反应,但这是我的一个宠儿。我看到Linux上有很多人想要在程序中获取有关特定PID的信息,而忽略了/ proc目录的存在。当然它是为这种事物创建的(以程序方式提取有关特定过程的信息)。
为了从&#39; Top&#39;中获取信息你需要调用外部程序,它需要一个fork和所有后续代码来管理那个分支 - 也许它在Perl中很容易,但是我已经习惯了C和C在那里有更多的开销然后我想要处理用。然后你必须编写一个正则表达式(排队引用&#39;现在你有两个问题&#39;)来解析输出。
直接从/ proc / entry读取只需要标准文件IO,并且/ proc的输出设计为以编程方式解析,因此不需要复杂的RExp来处理它。
Linux上的顶部从/ proc内部读取以获取其信息 - 所以我无法看到一个很好的理由不在这里切断中间人。我唯一能想到的就是便携性,因为有些* Nixs没有/ proc目录。但是再一次,Top输出的可移植性如何(BSD top和GNU top无论如何都可能略有不同)。