【问题标题】:How to get rid of bash control characters by evaluating them?如何通过评估它们来摆脱 bash 控制字符?
【发布时间】:2015-01-12 20:01:17
【问题描述】:

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

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

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

【问题讨论】:

  • 终端正在处理控制字符,而不是外壳。它们对非终端没有任何意义。手动剥离它们还不够吗?
  • 您的发行版中可能没有预先编写和包含的内容,但是编写一个逐字节读取文件并省略输出内容的过滤器应该不会太难不想要。您所需要的只是您要消除的不同字符/序列的列表...
  • @twalberg:我认为这并不是仅仅消除它们的问题(PHP 通过忽略它们来有效地做到这一点)。假设我运行了一个程序打印它的进度(0% 完成,5% 完成,10% 完成等等,不是写新行而是重写同一行)然后只是剥离控制字符将导致所有这些百分比值都在输出中,而我只希望有最新的。
  • @EtanReisner:感谢您的澄清,我会相应地更新我的问题。
  • 您通过可以理解终端控制字符的内容进行过滤。我不确定是否存在任何这样的东西(终端除外)。

标签: bash control-characters


【解决方案1】:

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

这是一个使用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 了解相关选项。

【讨论】:

    【解决方案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'
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-29
      相关资源
      最近更新 更多