【问题标题】:Block text isolation from log files从日志文件中阻止文本隔离
【发布时间】:2024-01-15 09:35:01
【问题描述】:

我倾向于在服务器启动期间查看日志文件中的错误,less 用于实现此目的。

但是,我想要更高效的东西。

我想查看“服务器停止”和“启动”两种模式之间的日志 我已经使用sed 实现了这一目标

sed -n '/Stopping/,/Server startup/p' test.txt

这工作正常,但有一个问题。日志文件一遍又一遍地包含这种模式(随着服务器的停止和启动),我怎样才能只获得这种模式的最后一个块? (这将是启动时服务器和日志的最后一次关闭)。

【问题讨论】:

  • 试试tac test.txt | sed -n '/Server startup/,/Stopping/{p;/Stopping/q}' | tac

标签: shell unix sed pattern-matching


【解决方案1】:

基于tacsed的简单解决方案:

tac test.txt  | sed -e '/stopping/,$d' |  tac | sed -e '/startup/,$d'

解释:

tac 反向连接和打印文件。

sed -e '/your_keyword/,$d' 输出从开始到到达 'your_keyword' 的行。

...所以从末尾开始打印您的日志文件,剪切第一部分,再次反转,剪切第二部分...等等!

测试它:

echo  "
xxxxxxxxxxx
xxxxxxxxxxx
xxx start xxxx
aaa1
aaa2
xx stop xxx
xxxyyyyxxxxyyyxxxx
xxxyyyyxxxxyyyxxxx
xyyyxx start xxxyyyyx
bbb1
bbb2
yy stop yy
yyyyyyyyy
yyyyyyyyy" | tac |sed -e '/start/,$d' |  tac | sed -e '/stop/,$d' 

输出:

bbb1
bbb2

【讨论】:

  • 如果我想在 echo 中包含 start 和 stop 怎么办?
  • 我想您将使用命令行过滤文件“test.txt”(如您的问题中所命名)以隔离日志块。 IE。 tac 测试.txt | sed -e ... ...所以我不清楚你在说什么“回声”。请澄清您的问题。
  • 对不起,我的意思是您的解决方案显示 bbb1 和 bbb2,这是我提供的两个文本字符串之间的内容。我要问的是我是否可以在所需的输出中包含“start”和“stop”字符串行,所以输出是“start”bbb1 bbb2“stop”
【解决方案2】:

这可能对你有用(GNU sed);

sed '/Stopping/,/Server startup/{/Stopping/h;//!H};$!d;x' file

将每个出现的所需行存储在保持空间 (HS) 中,并删除所有其他行。在文件结束时交换到 HS 并打印已存储的内容。

HS 中的最新行将覆盖任何以前的此类行。

【讨论】:

    【解决方案3】:

    永远不要使用范围表达式,因为它们会使琐碎任务的代码稍微简洁一些,但稍微有趣的任务需要完全重写或重复条件。只需使用 awk,您就可以简单地使用标志,而不必尝试强制范围工作,您甚至可以进行字符串比较,而不是在适当的情况下进行正则表达式比较。

    从包含5 的最后一行到包含8 的最后一行打印:

    $ seq 20 | awk '/5/{f=1;s=""} f{s=s $0 ORS} /8/{f=0} END{printf "%s", s}'
    15
    16
    17
    18
    

    【讨论】: