bash - shell中实时去除回车

标签 bash shell ffmpeg carriage-return

对于上下文,我试图创建一个 shell 脚本来简化 ffmpeg 的实时控制台输出,只显示正在编码的当前帧。我的最终目标是在某种批处理进度指示器中使用此信息。

对于那些不熟悉 ffmpeg 输出的人,它将编码的视频信息输出到 stdout,将控制台信息输出到 stderr。此外,当它真正开始显示编码信息时,它使用回车符来防止控制台屏幕被填满。这使得无法简单地使用 grep 和 awk 来捕获适当的行和帧信息。

我尝试的第一件事是使用 tr 替换回车符:

$ ffmpeg -i "ScreeningSchedule-1.mov"-y "test.mp4"2>&1 | tr '\r' '\n'

这是因为它向控制台显示实时输出。但是,如果我随后将该信息通过管道传递给 grep 或 awk 或其他任何东西,tr 的输出将被缓冲并且不再是实时的。例如:$ ffmpeg -i "ScreeningSchedule-1.mov"-y "test.mp4"2>&1 | tr '\r' '\n'>log.txt 生成的文件会立即填充一些信息,然后 5-10 秒后,更多行会被放入日志文件中。

起初我认为 sed 对此非常有用:$ # ffmpeg -i "ScreeningSchedule-1.mov"-y "test.mp4"2>&1 | sed 's/\\r/\\n/',但它会到达包含所有回车符的行并等待处理完成,然后再尝试执行任何操作。我认为这是因为 sed 是逐行工作的,需要整行都完成才能执行其他操作,然后它不会替换回车符。我已经为回车和换行尝试了各种不同的正则表达式,但尚未找到替代回车的解决方案。我运行的是 OSX 10.6.8,所以我使用的是 BSD sed,这可能是造成这种情况的原因。

我也尝试过将信息写入日志文件并使用 tail -f 读取它,但我仍然遇到实时替换回车符的问题。

我已经看到在 python 和 perl 中有解决方案,但是,我不愿意立即走那条路。首先,我不知道 python 或 perl。其次,我有一个功能齐全的批处理 shell 应用程序,我需要将其移植或弄清楚如何与 python/perl 集成。可能不难,但除非绝对必要,否则不是我想进入的领域。所以我正在寻找一个 shell 解决方案,最好是 bash,但任何 OSX shell 都可以。

如果我想要的根本不可行,那么我想当我到达那里时我会穿过那座桥。

最佳答案

如果只是管道后接收应用程序的输出缓冲问题。然后您可以尝试使用 gawk(和一些 BSD awk)或可以刷新缓冲区的 mawk。例如,尝试:

... | gawk '1;{fflush()}' RS='\r\n' > log.txt

或者,如果您的 awk 不支持这个,您可以通过重复关闭输出文件并附加下一行来强制执行此操作...

... | awk '{sub(/\r$/,x); print>>f; close(f)}' f=log.out

或者您可以只使用 shell,例如在 bash 中:

... | while IFS= read -r line; do printf "%s\n" "${line%$'\r'}"; done > log.out

关于bash - shell中实时去除回车,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16319179/

相关文章:

iphone - h264 授权、ffmpeg iPhone 转码

ios - 如何在 ffmpeg 中使用 librtmp?

bash - 如何将引用的参数传递给 GNU Parallel

linux - 如何在source之后捕获命令行参数

bash - "ls -1 path"中的-1是什么意思?

c++ - 在 C++ 中使用 Perl + Regex 将#define 更改为#undef

linux - 如何在linux shell脚本输出中缩短文件路径

bash - 如何使用 cut 为变量赋值?

android - 如何使用 ffmpeg/libavcodec/libstagefright

git - 从 shell 脚本检查 git push 的响应