![输出](https://linux22.com/image/108628/%E8%BE%93%E5%87%BA.png)
输入文件
Mar 21 13:25:04 ip-172-2-0-53 sendmail[5857]: v2LKMUDq005855: to=<[email protected]>,<[email protected]>, delay=00:02:34, xdelay=00:02:34, mailer=esmtp, pri=151745, relay=icadmed-com.mail.p...ction.googlemail.com. [xxx.xx.xxx.xxx], dsn=2.0.0, stat=Sent (<[email protected]> [InternalId=76295799050449, Hostname=BY1PR0701MB1752.namprd07.prod.gmail.com] 8962 bytes in 0.961, 9.102 KB/sec Queued mail for delivery)
Mar 21 11:34:55 ip-172-2-0-53 sendmail[5478]: v2LIXc00005476: to=<[email protected]>, delay=00:01:17, xdelay=00:01:17, mailer=esmtp, pri=120883, relay=gmail-com.mail.p...ction.googlemail.com. [xxx.xx.xxx.xx], dsn=2.0.0, stat=Sent (<[email protected]> [InternalId=79285096289546, Hostname=CY1PR07MB1448.namprd07.prod.googlemail.com] 8049 bytes in 0.226, 34.732 KB/sec Queued mail for delivery)
Mar 20 13:45:16 ip-172-2-0-53 sendmail[1295]: v2KKfjCN001293: to=<[email protected]>, delay=00:03:31, xdelay=00:03:31, mailer=esmtp, pri=120883, relay=mta5.am0.yahoodns.net. [xx.xxx.xx.xx], dsn=2.0.0, stat=Sent (ok dirdel)
Mar 20 08:54:57 ip-172-2-0-53 sendmail[32712]: v2KFss7V032710: to=<[email protected]>, delay=00:00:03, xdelay=00:00:03, mailer=esmtp, pri=120892, relay=mx4.hotmail.com. [xxx.xxx.xx.xxx], dsn=2.0.0, stat=Sent ( <[email protected]> Queued mail for delivery)
以及我检测到延迟超过 1 分钟的每行的预期输出
sendmail[5857]: delay=00:02:34 Hostname=BY1PR0701MB1752.namprd07.prod.gmail.com]
sendmail[5478]: delay=00:01:17 Hostname=CY1PR07MB1448.namprd07.prod.googlemail.com]
sendmail[1295]: delay=00:03:31
如何使用 shell 脚本解决这个问题?
答案1
这不再是 sed 选项。您必须解析时间为 的字符串00:01:00
,00:10:00
或者01:00:07
计算超过 60 秒。
我想出了一个 awk 文件
{ result = "" ;
for (i=1;i<=NF;i++) {
if ( $i ~ /^delay=/ ) {
s=split(substr($i,6) ,A,":") ;
t=60*A[1]+A[2] ;
#printf "%2d : %d mn (60x%s+%s) : %s\n",i,t,A[1],A[2],$i ;
if ( !t ) next ;
result = $i ;
}
if ( $i ~ /^Hostname/ ) result = result $i ;
}
if ( result != "" ) print result ;
}
一些提示:
( $i ~ /^foo/ )
将第 i 个字段与 foo 匹配(^
:模式开始)split(substr($i,6) ,A,":")
拆分数组 A 中的 H:M:S 部分A = B C
:将字符串 B 和 C 连接到 A
今天的示例给出了(u
是你的文件名,u.awk
是保存 awk 程序的文件)
awk -f u.awk u
delay=00:02:34, Hostname=BY1PR0701MB1752.namprd07.prod.gmail.com]
delay=00:01:17, Hostname=CY1PR07MB1448.namprd07.prod.googlemail.com]
delay=00:03:31,
答案2
sed 的工作
sed -e 's|^.* \(delay=[^ ]*\) .*\(Hostname=[^ ]*\) .*$|\1 \2|' file
在哪里
sed -e 's| ....l... | ... r ...|'
告诉 sed 用右手边替换左手边。^.* .* .*$
获取模式(.
是任何字符,*
任何数字,sapce 是空格,$
是行尾)\(delay=[^ ]*\) \(Hostname=[^ ]*\)
带字段的抓取模式(并对它们进行编号)\1 \2
替换我们发现的内容。
编辑: 去掉逗号
sed -e 's|^.* \(delay=[^,]*\), .*\(Hostname=[^ ]*\) .*$|\1 \2|' u
在哪里
- 使用
-i
(sed -i -s ...
) 就地编辑文件
答案3
试试这个命令
awk '{split($8,a,/=|:/);time_taken=a[2]*3600+a[3]*60+a[4]+0;if(time_taken>60){print $5,$8,$18}}' your_file.txt
split($8,a,/=|:/);
拆分第 8 列并计算秒。- 将时间与 60 秒进行比较
if(time_taken>60)
- 打印结果
{print $5,$8,$18}
答案4
我们在 Perl 正则表达式中使用负前瞻来获得 > 1 分钟的延迟
perl -lane '
BEGIN{
$,=$";
$dly=qr/\bdelay=(?!00:(?:00:[0-5][0-9]|01:00))(?:\d\d:\d\d:\d\d)(?=,)/;
}
/$dly/ and print /\b(?:Hostname|sendmail)\S+|$dly/g;
' yourfile
sed -e '
# logic for selecting entries where delay > 1 min
/[ ]delay=[0-9][0-9]:[0-9][0-9]:[0-9][0-9],/!d
/[ ]delay=[0][0]:[0][0]:[0-5][0-9],/d
/[ ]delay=[0][0]:[0][1]:[0][0],/d
# we are here => delay > 1 min, now fish out the entries...
s/^/\n\n/
s/[ ]sendmail[^ ]*/\n&\n/; s/\(\n\n.*\)\n\(.*\)\n/\2\1/
s/[ ]delay=[^, ]*/\n&\n/; s/\(\n\n.*\)\n\(.*\)\n/\2\1/
s/[ ]Hostname=[^ ]*/\n&\n/; s/\(\n\n.*\)\n\(.*\)\n/\2\1/
s/\n\n.*//;s/^\s*//
' yourfile
输出
sendmail[5857]: delay=00:02:34 Hostname=BY1PR0701MB1752.namprd07.prod.gmail.com]
sendmail[5478]: delay=00:01:17 Hostname=CY1PR07MB1448.namprd07.prod.googlemail.com]
sendmail[1295]: delay=00:03:31