附加到系统日志的文件特定条目

附加到系统日志的文件特定条目

像往常一样,我可以syslog通过以下方式检查条目的内容:

cat /var/log/syslog | grep myentry

我需要将所有myentry行附加到特定文件。当然,仅将上述命令的输出重定向到文件是行不通的,因为它会附加所有行,即使它们上次已添加。

我想到的第一个解决方案是在所有行之间循环,syslog直到找到目标文件的最后一行。然后我可以附加以下所有内容。定期执行此操作(即使用 cronjob 或更简单的 bash 中的定时循环)应该可以解决问题。

有没有更聪明或更优雅的方法来完成同样的工作?

编辑

我添加了 terdon 的要求:

我的系统日志示例:

Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]: CONNECT
Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]:  -- got it
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Ready
Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]: send (^M)
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete
Jan 17 13:03:18 stm32mp1-abc daemon.info pppd[14362]: Serial connection established.
Jan 17 13:03:18 stm32mp1-abc daemon.info pppd[14362]: Using interface ppp0

我想要附加到的现有文件的示例:

Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Ready

我期望这两个文件的最终输出:

Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Ready
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete

更新

好吧,看来我需要非常具体以示例为例,无论我的描述如何。新的例子:

系统日志

Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]: CONNECT
Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]:  -- got it
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Ready
Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]: send (^M)
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete
Jan 17 13:03:18 stm32mp1-abc daemon.info pppd[14362]: Serial connection established.
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Start operations
Jan 17 13:03:18 stm32mp1-abc daemon.info pppd[14362]: Using interface ppp0

电流输出

Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete

新输出

Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Start operations

应该清楚:

  1. 如果output文件为空,则追加所有syslog/myentries
  2. 如果output文件不为空,则追加所有下一个 syslog/myentries行(来自匹配的行)
  3. 如果output文件不为空且没有匹配项,则仍追加所有下一个 syslog/myentries行(最后一个时间戳之后)

如前所述,我可以使用蛮力来完成此操作:循环所有行,检查条件并在需要时追加。

我正在寻找更简单的解决方案,例如syslog自动拆分条目的提案,但我没有找到方法。

答案1

存储现有目标文件的最后一行。然后使用以下命令向后解析系统日志awk文件tac

p=$(tail -n1 output)
tac syslog | awk -v p="$p" '$0 == p{exit} /myentry/' | tac >> output

当找到最后一行(向后)时,awk将退出。如果找不到,或者输出最初为空,它将解析整个文件(我假设对于最初为空输出的情况,系统日志中没有空行)。同样,我们通过这种方式搜索所需的最少行,因此预计它对于大文件表现良好。


还要在你的工具箱中保留这个简单有效的命令:

awk '!seen[$0]++' output > output.tmp && mv output.tmp output

您可以随时运行,以修复目标文件,保留顺序(如果出于任何原因重复项设法传递到那里)。

答案2

这是一个简单的方法:

$ awk 'NR==FNR{a[$0]++; next}/myentry/ &&  !a[$0]' myentries syslog 
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete

这会选择新的匹配行,因此您所需要做的就是重定向到原始文件:

awk 'NR==FNR{a[$0]++; next}/myentry/ &&  !a[$0]' myentries syslog >> myentries

相关内容