问题:我需要找到在文件/var/log/syslog
和/var/log/syslog.1
.
tr
- 删除进程号,以便所有进程看起来都是平等的。cut
- 仅显示进程的名称。
另外,我认为我需要使用uniq
,sort
和head
命令。
答案1
服务名称位于 syslog 日志文件的第五列中(在具有默认 syslog 设置的 Ubuntu 计算机上找到)。它通常被列为servicename[pid]:
,例如CRON[1233]:
或ntpd[9283]:
等等。
获取第五个字段:
awk '{ print $5 }' /var/log/syslog
要删除该字段中的所有内容,请执行[
以下操作:
awk '{ sub("[[].*", "", $5); print $5 }' /var/log/syslog
现在你会得到一个类似的列表
dhclient
dhclient
dhclient
CRON
ntpd
CRON
CRON
ntpd
现在你只需对它们进行排序并计算它们,并保留最上面的:
awk '{ sub("[[].*", "", $5); print $5 }' /var/log/syslog |
sort | uniq -c | sort -rn | head -n 5
这可能会输出类似的内容
27 dhclient
23 CRON
13 ntpd
(这台特定机器上只有三个服务)。
要删除数字,请通过 进行过滤awk '{ print $2 }'
。
您也可以使用tr
和cut
,但恕我直言,这些工具对于这项工作来说有点太“简单”。cut
特别需要知道确切地要剪切多少个分隔符,因此如果列由多个空格字符分隔,则cut
需要考虑到这一点。
答案2
tr
不加区别地音译字符,这里不太合适,tr -d 0-9
会删除所有十进制数字,包括服务名称中的数字。将分隔符序列压缩为一个分隔符序列可能很有用,以便cut
可以使用。
您需要找到包含服务名称的列并从中提取服务名称。
它是哪一列取决于 syslog 的配置方式,特别是在时间戳格式方面。
您可以看到类似以下内容:
2018-03-13T07:17:01.506581-07:00 host CRON[26456]: (root) CMD (...)
其中服务名称位于第三列或:
Mar 14 00:35:01 host CRON[19234]: (root) CMD (...)
它在第五列的位置。
在后一种格式中,月份和日期列之间可以有 1 或 2 个空格(tr -s ' '
如果您想使用的话,您可以在cut
其中使用)。另请注意,不保证该[pid]
部分存在(例如内核日志或通过网络接收的日志(后者甚至可能没有“服务”列))。
适用于这两种不同格式(使用 GNU grep 或兼容 PCRE 支持的方法)的方法是:
grep -Po '^.{7}\S+ \S+ \K[^\s:[]+' /var/log/syslog |
sort |
uniq -c |
sort -rn |
head -n 5
也就是说,跳过前 7 个字符以及之后的所有非空格字符(这将覆盖两种格式的时间戳)和一个额外的列(\S+
两个空格之间:主机名),然后匹配除空格、冒号及其]
后(\K
标记匹配部分的开始)。
基于正则表达式的方法,这里使用功能更丰富的类似 perl 的方法,为您提供了更大的灵活性。同样的表达方式cut
为:
</var/log/syslog cut -c 8- |
cut -d ' ' -f3 |
cut -d : -f 1 |
cut -d '[' -f 1 |
sort |
uniq -c |
sort -rn |
head -n 5