我有一个包含多个控制字符的输出文件(即来自screen
的日志)。在屏幕内部,我运行的程序使用控制字符来刷新某些行(例如top
或打印进度条的任何内容)。
我想使用PHP输出此文件的tail
。如果我只是读取该文件并回显它的内容(使用PHP函数或通过调用tail
),输出会比最后几行更麻烦,因为它还包括已被覆盖的内容。如果我改为运行tail
在命令行中,它返回我想要的内容,因为终端会评估控制字符。
所以我的问题是:有没有办法评估控制字符,获取终端向我显示的输出,然后我可以在其他地方使用(例如,写入文件)?
答案 0 :(得分:2)
我不确定“评估”控制字符是什么意思,但你可以轻松地删除。
以下是使用sed
的示例,但如果您已经在使用PHP,则其内部正则表达式处理功能似乎更合适。命令
$ sed 's,\x1B\[[0-9?;]*[a-zA-Z],,g' file.dat
会将file.dat
的内容转储到标准输出,并移除所有ANSI escape sequences。 (而且我很确定除了你的文件包含无效的转义序列之外没有别的东西被删除,在这种情况下,操作无论如何都是错误定义的。)
这是一个小小的演示:
$ echo -e "This is\033[31m a \033[umessy \033[46mstring.\033[0m" > file.dat
$ cat file.dat
# The output of the above command is not shown to protect small children
# that might be browsing this site.
$ reset # your terminal
$ sed 's,\x1B\[[0-9?;]*[a-zA-Z],,g' file.dat
This is a messy string.
less
程序内置了一些更高级的逻辑,可以有选择地替换一些转义序列。请阅读the man page了解相关选项。
答案 1 :(得分:2)
@ 5gon12eder的答案摆脱了一些控制角色(多亏了!)但它没有处理对我来说更重要的回车部分。
我发现我可以删除从一行开头到该行内最后一个回车的任何内容,然后在此之后保留所有内容,所以这是我的sed命令实现的:
sed 's/^.*\r\([^\r]\+\)\r\?$/\1\r/g'
然后可以使用@ 5gon12eder的答案进一步清理输出:
cat screenlog.0 | sed 's/^.*\r\([^\r]\+\)\r\?$/\1\r/g' | sed 's,\x1B\[[0-9?;]*[a-zA-Z],,g'
结合起来,这看起来就像我想要的那样。