Linux 使用管道搜索文件的命令

Linux 使用管道搜索文件的命令

问题:我需要找到在文件/var/log/syslog/var/log/syslog.1.

  • tr- 删除进程号,以便所有进程看起来都是平等的。

  • cut- 仅显示进程的名称。

另外,我认为我需要使用uniq,sorthead命令。

答案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 }'


您也可以使用trcut,但恕我直言,这些工具对于这项工作来说有点太“简单”。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

相关内容