如何通过评估来摆脱 bash 控制字符?

How to get rid of bash control characters by evaluating them?

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

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

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

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

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

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

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

这是一个小演示:

$ echo -e "This is3[31m a 3[umessy 3[46mstring.3[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 了解相关选项。

@5gon12eder 的回答去掉了一些控制字符(谢谢!)但它没有处理对我来说更重要的回车 return 部分。

我发现我可以删除从一行开头到该行最后一个回车符 return 的所有内容,然后简单地保留所有内容,所以这是我的 sed 命令:

sed 's/^.*\r\([^\r]\+\)\r\?$/\r/g'

然后可以使用@5gon12eder 的回答进一步清理输出:

cat screenlog.0 | sed 's/^.*\r\([^\r]\+\)\r\?$/\r/g' | sed 's,\x1B\[[0-9?;]*[a-zA-Z],,g'

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