【问题标题】:Linux Bash Print largest number in column from monthly rotated log fileLinux Bash 从每月轮换的日志文件中打印列中的最大数字
【发布时间】:2023-01-20 17:32:37
【问题描述】:

我有每月轮换的日志文件,看起来像下面的输出。这些文件的名称为transc-2301.log (transc-YMM)。一年中的每个月都有一个文件。我需要一个简单的 bash 命令来查找当月的文件,并显示第 3 列的最大数字 (max)。在下面的示例中,输出应为 87

01/02/23 10:45  19      26
01/02/23 11:45  19      45
01/02/23 12:45  19      36
01/02/23 13:45  22      64
01/02/23 14:45  19      72
01/02/23 15:45  19      54
01/02/23 16:45  19      80
01/02/23 17:45  17      36
01/03/23 10:45  18      24
01/03/23 11:45  19      26
01/03/23 12:45  19      48
01/03/23 13:45  20      87
01/03/23 14:45  20      29
01/03/23 15:45  18      26

【问题讨论】:

  • “我需要一个简单的 bash 命令” - 好的,从最少的编码工作开始并发布它
  • 是的,我发现 awk '{if ($4 > max) max=$4}END{print max}' transc-2301.log 可以正常工作,但需要在文件名中获取“日期 +"%y%m""

标签: shell awk


【解决方案1】:

由于您的文件名是可排序的,因此您可以轻松地将当月的文件选为可排序序列中的最后一个文件。比快速 awk 返回结果。

for file in transc_*.log; do :; done
awk '($3>m){m=$3}END{print m}' "$file"

或者你可以让 awk 对文件名做繁重的工作

awk 'BEGIN{ARGV[1]=ARGV[ARGC-1];ARGC=2}($3>m){m=$3}END{print m}' transc_*.log

或者如果你不喜欢 glob-expansion 技巧:

awk '($3>m){m=$3}END{print m}' "transc_$(date "+%y%m").log"

【讨论】:

  • 第二种选择是完美的。谢谢!
【解决方案2】:

我将按照以下方式利用 GNU AWK 完成此任务,让 transc-2301.log 内容成为

01/02/23 10:45  19      26
01/02/23 11:45  19      45
01/02/23 12:45  19      36
01/02/23 13:45  22      64
01/02/23 14:45  19      72
01/02/23 15:45  19      54
01/02/23 16:45  19      80
01/02/23 17:45  17      36
01/03/23 10:45  18      24
01/03/23 11:45  19      26
01/03/23 12:45  19      48
01/03/23 13:45  20      87
01/03/23 14:45  20      29
01/03/23 15:45  18      26

然后

awk 'BEGIN{m=-1;FS="[[:space:]]{2,}";logname=strftime("transc-%y%m.log")}FILENAME==logname{m=$3>m?$3:m}END{print m}' transc*.log

给出输出(截至 2023 年 1 月 18 日)

87

警告:我假设您的文件使用两个或多个空白字符作为分隔符,如果这不成立,请相应地调整FS警告:将m 设置为低于可能出现在感兴趣列中的最低值的值。说明:我使用 strftime 函数来检测应该处理什么文件并 ram 所有 transc*.log 文件,但只对选定的文件采取行动,行动是:如果它高于当前 @987654333,则将 m 设置为 $3 @否则保留m值。处理文件后,在END中,我print值为m

(测试 ub GNU Awk 5.0.1)

【讨论】:

  • 这会处理所有文件的每一行,即使您不需要处理该文件。
【解决方案3】:
mawk '_<(__ = +$NF) { _=__ } END { print +_ }'

gawk 'END { print +_ } (_=_<(__=+$NF) ?__:_)<_' 
87

【讨论】:

  • ___ 非常模糊
  • @kvantour:因为叫他们ij更好吗?
  • 它只是更具可读性,人们更倾向于理解它。不是字母数字的变量可以解释为特殊变量(例如 bash 中的 _)。读者可以在这种情况下做出类似的假设。如果您的代码更具可读性,您的答案可能会获得更多赞成票。我不是说它错了,我只是说读者需要更多时间来理解它,因为他们不习惯阅读主要是非字母数字字符的代码。
  • @kvantour:这就是为什么有人使用实际示例很重要,例如发布问题的解决方案,作为展示原因的方法,不像bashperl$_ | _并不特别 根本awk,并希望消除这种广泛存在的误解......。
  • 你的说法不正确。在 awk 中,未初始化的变量是 strnum 类型(字符串和数字)。可以表示数字的字段也是strnum类型的。两个 strnum 之间的任何比较都将是数字和未初始化的变量,然后数字为零。如果您搜索最大值,但所有数字都是负数,这将失败。
猜你喜欢
  • 2013-02-17
  • 2018-03-25
  • 2011-04-11
  • 2019-06-13
  • 1970-01-01
  • 2015-03-26
  • 2021-07-11
  • 2013-04-18
  • 1970-01-01
相关资源
最近更新 更多