为了在非常繁忙的服务器上调试 Apache,我们使用 strace 来记录我们所有的进程。现在,我在一个文件夹中有 1000 条单独的 strace,我需要找到值为 1.0+ 或更大的那些。这是我们用来生成 straces 的命令
mkdir /strace; ps auxw | grep httpd | awk '{print"-p " $2}' | xargs strace -o /strace/strace.log -ff -s4096 -r
这会生成名为 strace.log.29382 的文件(其中 29382 是进程的 PID)。
现在,如果我运行这个命令:
for i in `ls /strace/*`; do echo $i; cat $i | cut -c6-12 | sort -rn | head -c 8; done
它将输出文件名和顶级运行时值。即
/strace/strace.log.19125
0.13908
/strace/strace.log.19126
0.07093
/strace/strace.log.19127
0.09312
我要找的只是输出那些值为 1.0 或更大的值。
示例数据:https://pastebin.com/Se89Jt1i
此数据不包含任何 1.0+ 内容,但它是第一组 #s 仅尝试过滤。
我不想显示的内容
0.169598 close(85) = 0
我想找到什么
1.202650 accept4(3, {sa_family=AF_INET, sin_port=htons(4557), sin_addr=inet_addr("xxx.xxx.xxx.xxx")}, [16], SOCK_CLOEXEC) = 85
我的猫对值进行排序,因此文件中的最大值总是排在第一位。
最佳答案
因为我比较习惯用perl,一个用perl的解决方案,应该可以用awk翻译。
一行
perl -ane 'BEGIN{@ARGV=</strace/*>}$max=$F[0]if$F[0]>$max;if(eof){push@A,$ARGV if$max>1;$max=0};END{print"$_\n"for@A}'
无需对文件进行排序以获得最大值,只需将其存储在变量中即可。可以有趣修改以获取信息的部分:
push@A,$ARGV
可以改成
push@A,"$ARGV:$max"
获取值。
工作原理:
- -a 标志:来自 perl -h :
autosplit mode with -n or -p (splits $_ into @F)
默认情况下由一个或多个空格分隔。 -
BEGIN{}
和END{}
block 在开始和结束时执行,不在这些 block 中的部分与 awk 一样为每一行执行。 -
</strace/*>
是一个全局匹配,它给出了一个文件列表 -
@ARGV
是一个包含命令行参数的特殊数组(这里是要处理的文件列表) -
eof
是一个函数,当当前行是当前文件的最后一行时返回 true -
$ARGV
是当前文件名 -
push
将元素追加到数组中
带有警告的脚本版本,有助于修复错误。
#!/usr/bin/perl
use strict;
use warnings;
sub BEGIN {
use File::Glob ();
@ARGV = glob('/strace/*');
}
my (@A,@F);
my $max = 0;
while (defined($_ = readline ARGV)) {
@F = split(' ', $_, 0);
$max = $F[0] if $F[0] > $max;
if (eof) {
push @A, "${ARGV}:$max" if $max > 1;
$max = 0;
}
}
print "$_\n" foreach (@A);
关于linux - 使用 cut 将 cat 限制为值 1 或以上 我不这样做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46059999/