对于上下文,我尝试创建一个 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)