我有长时间运行的程序可以重新启动其内部状态。我只想查看最新状态的日志文件条目(加载到vim
的快速修复中)。如何显示之后的所有行最后的字符串的出现STARTING SESSION
?
我当前的解决方案(日志文件有时长达 GB,因此我从不查看超过最后 5000 行的内容):
tail -n5000 logfile.log | grep -B5000 -v -e 'STARTING SESSION'> shortened.log
当会话产生大量日志记录时,这很有效,但如果我的日志较短且多次重新启动,则它会包含多个会话。
本质上,我想要一个类似--reverse
标志的东西,它可以使 grep 从文件末尾而不是开头进行搜索:
grep --reverse --after-context=5000 --max-count=1 'STARTING SESSION' logfile.log
笔记:
问题类似于在第 n 次出现匹配后打印行,但我想要最后一次出现。
问题几乎是一样的在 POSIX.2 中获取从最后一个标记到 EOF 的文本只是我没有 POSIX 要求并且我的文件很大。我更喜欢使用 GNU utils 的有效解决方案(我正在使用mingw64
)。
答案1
反转文件,显示它直到第一次出现,然后再次反转输出:
tac logfile.log | sed '/STARTING SESSION/q' | tac
tac
当给定一个常规(可查找)文件来处理时是有效的,并且由于sed
一旦看到起始行就退出,整个管道将仅根据需要处理日志文件的末尾(向上舍入到tac
's、sed
's 和内核缓冲区大小)。这应该可以很好地扩展到大文件。
tac
是一个 GNU 实用程序。在非 GNU 系统上,您通常可以用来tail -r
执行相同的操作。
如果日志文件根本没有“STARTING SESSION”行,则不会产生与您的行为相同的行为grep
:它将输出完整的日志文件。为了避免这种情况,有一个变体拘萨罗南达的方法可以使用:
tac logfile.log | sed -n '/STARTING SESSION/{H;x;p;q;};H' | tail -n +2 | tac
表达式sed
查找“STARTING SESSION”,匹配时将当前行追加到保持空间,将保持空间与模式空间交换,输出并退出;任何其他行都将附加到保留空间。tail -n +2
用于跳过第一个空行(将模式空间附加到保留空间会添加一个前导换行符)。
答案2
使用sed
没有tac
:
sed \
-e '/STARTING SESSION/h' \
-e '//,$ { //!H; }' \
-e '$!d' \
-e x logfile.log
或者,;
在单行的表达式之间使用,
sed '/STARTING SESSION/h; //,$ { //!H; }; $!d; x' logfile.log
带注释的变体:
# If this line matches our trigger, save buffer in hold-space (overwrites).
/STARTING SESSION/ h
# In the range from the trigger to the end, append buffer to hold-space,
# but only if the current line isn't the trigger.
# (// re-uses the most recent expression)
//,$ { //!H; }
# If we're not at the end, restart with the next line without outputting anything.
$! d
# At the end, swap the hold-space into the buffer.
x
# (buffer is implicitly printed)
摘要:该sed
脚本将触发器和文档末尾之间的所有行保存在sed
.每当找到触发器时,保持空间就会被清除。最后,输出保持空间。
如果未找到触发器,则不会产生任何输出。
还要注意,这必须读取整个文件。
类似的方法awk
:
awk '
/STARTING SESSION/ { delete hold; i = 1 }
i { hold[i++] = $0 }
END { for (j = 1; j < i; j++) print hold[j] }' logfile.log
hold
在这里,一旦找到触发器(当我们i
第一次设置为 1 时),我们将开始在数组中收集数据。我们删除收集的数据,并i
在每次触发时重置为 1。
最后,输出所有收集的行。
该delete hold
声明并不是严格需要的。