ANSI 代码转换器

ANSI 代码转换器

是否有任何工具可以将 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' | \
...

这是我做的快速测试的一部分伊尔西记录。

但想知道是否有现有的工具可以完成这项工作。

作为旁注,我们有ahaAnsi 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 终端格式,这是该函数的主要目的。

相关内容