我可以使用 unix utils 以编程方式将 ANSI 控制代码“烧录”到文件中吗?

Posted

技术标签:

【中文标题】我可以使用 unix utils 以编程方式将 ANSI 控制代码“烧录”到文件中吗?【英文标题】:Can I programmatically "burn in" ANSI control codes to a file using unix utils? 【发布时间】:2015-03-31 21:35:26 【问题描述】:

示例:我以script 开始录制,并尝试输入echo test 但省略了o,所以我退格来更正它。

当我 cat typescript 时,一切看起来都很正常,因为代码已被解释,但如果我使用 lessvim 我看到 ech test^H^[[K^H^[[K^H^[[K^H^[[K^H^[[Ko test^M

我完全理解这是什么以及为什么会发生这种情况,但是有没有办法“烧入”代码并在文件中查看结果?我笨拙的方法是 cat 文件,然后从终端复制/粘贴文本,但是 cat、sed、awk 或其他东西的组合肯定可以让我更轻松地到达那里?

【问题讨论】:

试试less -r typescriptless -R typescript 啊,这很酷,我不知道 -r。有什么办法可以将其保存到文件中? less -r typescript > newfile 没用。 看起来像个骗子。 this stackexchange question。我最喜欢最后一个。 乔,我刚刚添加了一个带有sed 命令的答案,该命令应该删除大部分这些序列。 @John1024:恐怕less -r/-R 在这个问题上不会比普通的cat 做得更好。 【参考方案1】:

要显示包含 ANSI 序列的文件,

less -r typescript

或者,

less -R typescript

要从文件中删除 ANSI 和退格序列,创建一个干净的 newfile,尝试:

sed -r ':again; s/[^\x08]\x08\x1b\[K//; t again; s/\x1b_[^\x1b]*\x1b[\]//g; s/\x1B\[[^m]*m//g' typescript >newfile

工作原理

-r

这会打开扩展正则表达式。 (在 BSD 系统上,-r 应替换为 -E。现代版本的 GNU sed 将接受 -r-E。)

`:再次; s/[^\x08]\x08\x1b[K//;又来了

这将删除所有退格序列。这些是在循环中一次完成的。

s/\x1b_[^\x1b]*\x1b[\]//g

作为xterm 扩展(请参阅documentation),Esc _ something Esc \ 将无能为力。此命令会删除这些序列。

s/\x1B\[[^m]*m//g

这将删除设置颜色等的剩余 ANSI 序列。

这涵盖了我通常遇到的所有控制序列。有各种各样的扩展控制序列,如果你的输出有一些我没有看到的,代码可能需要扩展。

POSIX 或 BSD sed

在 BSD 或 POSIX 系统上,单独的命令必须用-e 选项而不是分号链接在一起。因此,尝试:

sed -e ':again' -e 's/[^\x08]\x08\x1b\[K//' -e 't again' -e 's/\x1b_[^\x1b]*\x1b[\]//g' -e 's/\x1B\[[^m]*m//g'

【讨论】:

【参考方案2】:

使用“sed -r”的建议答案依赖于 GNU sed,这使得它不是真正可移植的。可以使用 POSIX sed 执行相同的功能,但不同的是:POSIX 不提供在命令选项中传递整个脚本,如此处所示。这意味着实现循环的(POSIX)方式将在一个单独的文件中,使用“-f”选项传递给 sed。同样,十六进制常量不可移植。进行这些更改后,可以在 BSD 和 Unix 系统上使用功能等效的脚本。

建议的答案也没有涵盖一些相当常见的回车使用(例如在 yum 输出中),也没有过滤掉“大多数” ANSI 序列(因为它专注于 SGR “m” final特点)。最后是指

escape _ text _

作为 xterm 扩展。但是 xterm 没有提供这样的扩展,因为“escape”和“_”这两个字符开始一个 Application Program Command 序列(而 xterm 没有实现)。

生成的 sed 脚本如下所示(“^[”是转义字符):

s/^[[[][<=>?]\0,1\[;0-9]*[@-~]//g
s/^[[]][^^[]*^G//g
s/^[[]][^^[]*^[\\//g
:loop
s/[^^H]^H\(.\)/\1/g
t loop
s/^M^M*$//g
s/^.*^M//g
s/^[[^[]//g

可以在here 找到更完整的脚本,名为“script2log”。但是,有些东西(例如 CSI K)不适合 sed 脚本。

【讨论】:

以上是关于我可以使用 unix utils 以编程方式将 ANSI 控制代码“烧录”到文件中吗?的主要内容,如果未能解决你的问题,请参考以下文章

《Unix 网络编程》15:Unix 域协议

如何通过 Perl 以编程方式控制交互式 Unix 应用程序?

从 JUNIT 以编程方式在远程 Unix 服务器上运行 WireMock

在 VBA 中,如何以简单的方式将 UTC UNIX 时间戳转换为本地时区日期?

unix高级环境编程看了能写项目吗

如何以编程方式确定 Java 中的操作系统?