是否有任何工具可以将 ANSI 代码文本转换为类似文本的输出?tput
上限名称或类似名称?
询问的原因是我想使用script
或类似的方法并查看结果文件,而不必破译 ANSI 序列。我知道一些,但不是全部,文本输出会更容易阅读。
在大多数情况下,我可以查看生成 ANSI 文本的脚本或程序的源代码,但如果有一个类似“调试”的工具就更好了。
最好的可能是C?变量名称,即:
^[[K -> <clr_eol>
知道我可以为它编写一个脚本......例如:
sed 's/$/<newline>/' rec001.txt | \
sed 's/\x07/\n<bell>/g' | \
sed 's/\x1b\[K/\n<clr_eol>/g' | \
sed 's/\x1b\[?12l\x1b\[?25h/\n<cursor_normal>/g' | \
sed 's/\x1b\[\([0-9]\+\);\([0-9]\+\)H/\n<cursor_position(\1, \2)>/g' | \
sed 's/\x1b\[?1049h/\n<enter_ca_mode>/g' | \
sed 's/\x1b\[?25l/\n<cursor_invisible>/g' | \
sed 's/\x0d/<CR>/g' | \
...
这是我做的快速测试的一部分伊尔西记录。
但想知道是否有现有的工具可以完成这项工作。
作为旁注,我们有aha
,Ansi HTML 适配器,它将 ANSI 转换为 HTML。但这不是我正在寻找的适配器。
答案1
有人可能会建议一个程序。这不是一个小问题出色地:
- “ANSI 序列”在 ECMA-48 中标准化,
- 您的一些示例(例如光标外观和进入_ca_模式)不在标准中,
- 一些例如进入_ca_模式
1049
代码有变化 (\E7\E[?47h
)。如果程序依赖于终端描述,则只能识别其中一种变体, - 一些序列是参数化的,这意味着程序必须内置规则,或者能够将终端功能(例如转换为
\E[%i%p1%d;%p2%dH
可以与输入匹配的正则表达式)转换为终端功能。
考虑到所有这些,如果有人建议一个程序,它很可能不会解决这些方面,而只是一个没有显示器的终端模拟器。
答案2
如果您只想要 ANSI 光标移动,您可以使用 NPM 模块轻松创建解释器节点反解析器。我为我的 JavaScript 库使用了相同的模块:jQuery 终端,我在这里解析和处理 ANSI 转义和改写(man 命令的输出)。
你可以在GitHub上看看我是如何使用解析器的unix_formatting.js(该文件包括 ansi-parser)。您可以尝试修改代码以仅处理文本并忽略颜色(jQuery 终端格式语法)。应该没那么难。
如果您想要快速处理,可以创建一个脚本来处理文件并删除 jQuery Terminal 使用的格式。这是一个可以解决问题的快速技巧(但您可能最好修改 unix_formatting.js 文件并删除所有不需要的内容)。
要开始使用 jQuery 终端,请使用以下命令:
mkdir ansi-text
cd ansi-text
npm init -y # you need nodeJS installed
npm install jquery.terminal
然后在同一目录中创建此文件:
ansi-text.js
#!/usr/bin/env node
// mock jQuery that is not actually required
const $ = global.$ = global.jQuery = {
fn: {
extend: function(obj) {
Object.assign(global.jQuery.fn, obj);
}
},
extend: Object.assign
};
global.navigator = {
userAgent: 'Node'
};
require('jquery.terminal')(global, global.$);
require('jquery.terminal/js/unix_formatting')(global, global.$);
read_stdin().then(function(buff) {
const str = buff.toString();
const formatted = $.terminal.apply_formatters(str);
console.log($.terminal.strip(formatted));
});
function read_stdin() {
return new Promise((resolve) => {
const buff = [];
process.stdin.on('data', data => {
buff.push(data);
}).on('end', () => {
var len = buff.map(x => x.length).reduce((acc, e) => acc + e);
resolve(Buffer.concat(buff, len));
});
});
}
然后您可以创建测试脚本:
测试文件
tput cup 2 3;
echo HELLO;
tput cup 5 20;
echo WORLD;
你可以看到它的工作原理是:
unbuffer ./test.sh | ./ansi-text.js
输出:
kuba@jcubic:~/projects/jcubic/ansi-text$ unbuffer test.sh | ./ansi-text.js
HELLO
WORLD
kuba@jcubic:~/projects/jcubic/ansi-text$
unbuffer 将使脚本认为它是 TTY (它是 Expect 的一部分)。
JS 代码不处理终端的宽度,但在转换 ANSI 转义后可以轻松添加它。要分割输出,请使用:$.terminal.split_equal(string, cols)
但您可能可以使用更简单的东西,因为您不需要处理 jQuery 终端格式,这是该函数的主要目的。