[英]awk to print header and lines matching specific criteria
我正在打印iostat
或类似的输出,例如:
[/] # iostat -xnCT d 5 5
Tue Nov 25 13:45:56 2014
extended device statistics
r/s w/s kr/s kw/s wait actv wsvc_t asvc_t %w %b device
0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.1 0 0 c0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.1 0 0 c0t0d0
0.1 2.7 1.6 4.8 0.0 0.0 0.1 433.2 0 0 c1
0.1 2.7 1.5 4.8 0.0 0.0 0.1 3.3 0 0 c1t0d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 100.1 0 0 c1t1d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c1t2d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0 0 c1t3d0
0.1 0.1 0.1 0.0 0.0 0.0 0.0 600.0 0 0 c2
0.0 0.0 0.0 0.0 0.0 0.0 185.0 0.0 0 0 c2t0d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t1d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0 0 c2t4d0
0.0 0.0 0.0 0.0 0.0 0.0 295.0 0.0 0 0 c2t5d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0 0 c2t6d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t8d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t9d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t10d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0 0 c2t11d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t12d0
0.1 0.1 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3t0d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3t1d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3t2d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3t3d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3t4d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3t5d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3t6d0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c3t8d0
我生成这些日志,然后使用脚本打印出信息。 现在,我正在研究一些性能脚本,例如,需要grep来获取始终生成的日志文件中具有较高平均服务时间的值,并查看大于100的实例值。
所以这是我能做的:
awk '$7 > 100 || $8 > 100' filename
因此,我将获得wsvc_t和asvc_t的值都大于100的所有条目。注意,这只是一个示例。 但是,我也想在发生这种情况时打印日期,这无法使用grep -B来完成,或者我不确定如何使用sed或awk来执行此操作,因为输入之前的行数不会是固定的一。
因此,有什么简单的方法可以打印$ 7或$ 8的值大于100的行,然后在找到的条目上方打印包含2014或年份的行?
所以我的结果应该是这样的:
Tue Nov 25 13:45:56 2014
extended device statistics
r/s w/s kr/s kw/s wait actv wsvc_t asvc_t %w %b device
0.1 2.7 1.6 4.8 0.0 0.0 0.1 433.2 0 0 c1
0.0 0.0 0.0 0.0 0.0 0.0 0.0 100.1 0 0 c1t1d0
0.1 0.1 0.1 0.0 0.0 0.0 0.0 600.0 0 0 c2
0.0 0.0 0.0 0.0 0.0 0.0 185.0 0.0 0 0 c2t0d0
0.0 0.0 0.0 0.0 0.0 0.0 295.0 0.0 0 0 c2t5d0
日志文件将在数千行中运行。
您需要在传递时将有趣的头数据捕获到变量中。 然后,当看到一堆有趣的行时,您需要选择一次打印标题。 最后,您需要重置一个事实,即每次看到新日期时都打印标题。
您首选的语言是什么? 我不是awk关于模式的最新功能。 当我开始使用Perl时,我不再关心。 因此,这是一些未经测试的Perl代码:
source-process-feeding-lines | perl -n -e '
if(/^(\w+ \w+ \d+ \d+:\d+:\d+ \d+)$/) {
$date = $1;
$header1 = $header2 = $printed = undef; # reset heading state
continue; # next line please
}
if(/extended device statistics/) {
$header1 = $_;
continue;
}
if(/^(\s*\w\/\w.*device)$/ { # simple but probably sufficient recogniser
$header2 = $_;
continue;
}
# assume a data line here
if(/your pattern for an interesting line/) {
if(! $printed) {
$printed = 1; # prevent a 2nd printing unless the date changes
print $date, $header1, $header2;
}
print; # print your interesting line
}
'
这已经足够接近我认为的要求。 调试可能需要应用!
我将使用以下内容:
awk 'NR<=3 || $7 > 100 || $8 > 100'
这将打印符合以下任一条件的行:
NR<=3
。 NR
代表记录数,通常是行数。 因此,我们正在寻找行号小于或等于3(以打印标题)。 因此,我添加到当前脚本中的唯一一件事就是NR<=3
,当像现在这样确切地知道我们要打印的行号时,它非常有用。
将给定的输入存储为文件:
$ awk 'NR<=3 || $7 > 100 || $8 > 100' file
Tue Nov 25 13:45:56 2014
extended device statistics
r/s w/s kr/s kw/s wait actv wsvc_t asvc_t %w %b device
0.1 2.7 1.6 4.8 0.0 0.0 0.1 433.2 0 0 c1
0.0 0.0 0.0 0.0 0.0 0.0 0.0 100.1 0 0 c1t1d0
0.1 0.1 0.1 0.0 0.0 0.0 0.0 600.0 0 0 c2
0.0 0.0 0.0 0.0 0.0 0.0 185.0 0.0 0 0 c2t0d0
0.0 0.0 0.0 0.0 0.0 0.0 295.0 0.0 0 0 c2t5d0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.