我可以使用 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
时,一切看起来都很正常,因为代码已被解释,但如果我使用 less
或 vim
我看到 ech test^H^[[K^H^[[K^H^[[K^H^[[K^H^[[Ko test^M
我完全理解这是什么以及为什么会发生这种情况,但是有没有办法“烧入”代码并在文件中查看结果?我笨拙的方法是 cat
文件,然后从终端复制/粘贴文本,但是 cat、sed、awk 或其他东西的组合肯定可以让我更轻松地到达那里?
【问题讨论】:
试试less -r typescript
或less -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 控制代码“烧录”到文件中吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Perl 以编程方式控制交互式 Unix 应用程序?
从 JUNIT 以编程方式在远程 Unix 服务器上运行 WireMock