为什么grep命令的输出结果会随终端宽度不同而发生变化?
问题原因
- 你生成的txt文件内容结构特殊:ffmpeg输出进度信息时,为了实现终端内同一行刷新进度的效果,所有进度行之间用回车符(
\r,ASCII 0x0D)分隔,而不是常用的换行符(\n)。而grep默认仅以\n作为行分隔符,因此所有ffmpeg进度内容+最后的blackdetect日志,在grep的识别逻辑里属于同一个逻辑行,只要命中blackdetect关键词,grep就会把这整段连在一起的内容全部输出。 - 终端显示规则导致不同宽度下呈现结果不同:
- 终端默认遇到
\r时,会将光标移动到当前行的行首,后续输出的内容会覆盖当前行已有的内容。 - 当终端宽度足够(≥81字符)时,整段grep输出的内容可以在同一行内完成打印,前面的frame进度内容会被后面
\r引导的内容完全覆盖,最终只显示最后的blackdetect日志,也就是你认为的正确结果。 - 当终端宽度不足(≤80字符)时,输出内容到达终端右边界后会自动换行,后续的
\r只能将光标定位到新行的行首,无法覆盖上一行残留的frame进度内容,因此会出现多余的前置进度信息。
- 终端默认遇到
修复方案
- 方案1:搜索时直接处理文件中的回车符,将其转为换行符后再grep,兼容性最强:
tr '\r' '\n' < 01.txt | grep blackdetect - 方案2:grep拿到结果后,删除所有回车符之前的内容,仅保留最后一段有效输出:
grep blackdetect 01.txt | sed 's/.*\r//' - 方案3:生成ffmpeg日志的时候就提前处理回车符,避免后续使用时出现异常:
# 运行ffmpeg时直接把回车替换为换行再存入文件 ffmpeg [你的原有ffmpeg参数] 2>&1 | tr '\r' '\n' > 01.txt
内容的提问来源于stack exchange,提问作者Gamer2015
相关产品推荐
相关产品推荐

