1

screen我有一个包含多个控制字符的输出文件(即来自 的日志)。在屏幕内部,我运行了使用控制字符刷新某些行的程序(示例将是top或任何打印进度条)。

我想tail使用 PHP 输出这个文件。如果我只是读入该文件并回显其内容(使用 PHP 函数或通过调用tail),输出会很混乱,而且比最后几行要多得多,因为它还包括已被覆盖的内容。如果我改为tail在命令行中运行,它返回我想要的,因为终端会评估控制字符。

所以我的问题是:有没有办法评估控制字符,得到终端显示的输出,然后我可以在其他地方使用(例如,写入文件)?

4

2 回答 2

2

我不确定您所说的“评估”控制字符是什么意思,但您可以轻松删除它们。

这是一个使用示例,sed但如果您已经在使用 PHP,那么它的内部正则表达式处理功能似乎更合适。命令

$ sed 's,\x1B\[[0-9?;]*[a-zA-Z],,g' file.dat

会将 的内容转储file.dat到标准输出,并删除所有ANSI 转义序列。(而且我很确定不会删除任何其他内容,除非您的文件包含无效的转义序列,在这种情况下,无论如何操作都是不明确的。)

这是一个小演示:

$ 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程序内置了一些更高级的逻辑,可以选择性地替换一些转义序列。阅读手册页以获取相关选项。

于 2015-01-12T22:31:20.797 回答
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'

结合起来,这看起来和我想要的完全一样。

于 2015-01-13T13:29:28.433 回答