Есть ли какой-либо инструмент, который преобразует текст с кодировкой 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
,Адаптер HTML Ansi, который преобразует ANSI в HTML. Но это не тот адаптер, который я ищу.
решение1
Кто-то может предложить программу. Это не тривиальная задача сделатьхорошо:
- «Последовательности ANSI» стандартизированы в ECMA-48,
- некоторые из ваших примеров (например, внешний вид курсора ивведите_ca_mode) не входят в стандарт,
- некоторые, такие каквведите_ca_mode
1049
код имеет вариации (\E7\E[?47h
). Если программа опирается на описание терминала, будет распознана только одна из вариаций, - некоторые последовательности параметризованы, что означает, что программа должна либо иметь встроенные правила, либо иметь возможность преобразовывать возможности терминала, например,
\E[%i%p1%d;%p2%dH
в регулярное выражение, которое можно сопоставлять с входными данными.
Учитывая все это, если кто-то предложит программу, она, скорее всего, не решит эти аспекты, а будет просто эмулятором терминала без дисплея.
решение2
Если вам нужно только перемещение курсора ANSI, вы можете легко создать интерпретатор с помощью модуля NPM.узел-ансипарсер. Я использовал тот же модуль для своей библиотеки JavaScript:jQuery-терминал, где я анализирую и обрабатываю экранированные последовательности ANSI и перезаписываемые символы (вывод команды man).
Вы можете посмотреть, как я использовал парсер на GitHub.unix_formatting.js(файл включает в себя ansi-parser). Вы можете попробовать изменить код так, чтобы он обрабатывал только текст и игнорировал цвета (синтаксис форматирования jQuery Terminal). Это не должно быть так уж сложно.
Если вам нужно что-то быстрое, вы можете создать скрипт, который просто обработает файл и удалит форматирование, используемое jQuery Terminal. Вот быстрый хак, который делает это (но вам, вероятно, лучше будет изменить файл unix_formatting.js и удалить все, что не нужно).
Для начала работы с jQuery Terminal используйте следующее:
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, а это и есть основная цель функции.