Gibt es ein Tool, das Text mit ANSI-Code in eine textähnliche Ausgabe konvertiert? tput
Großbuchstaben oder ähnliches?
Grund der Anfrage ist, dass ich gerne script
o.ä. verwenden und die resultierende Datei anzeigen möchte, ohne ANSI-Sequenzen entziffern zu müssen. Einige kenne ich, aber nicht alle, und eine Textausgabe wäre leichter zu lesen.
In den meisten Fällen kann ich mir den Quellcode des Skripts oder Programms ansehen, das den ANSI-Text erstellt, aber es wäre schön, wenn es ein „Debug“-ähnliches Tool gäbe.
Das Beste wäre wahrscheinlich C?Variablennamen, also:
^[[K -> <clr_eol>
Ich weiß, dass ich dafür ein Skript schreiben kann ... zum Beispiel:
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' | \
...
Das ist Teil eines Schnelltests, den ich an einemIrssiAufzeichnung.
Ich frage mich aber, ob es für diese Aufgabe bereits Werkzeuge gibt.
Als Randbemerkung haben wir aha
,Ansi-HTML-Adapter, der ANSI in HTML konvertiert. Aber das ist nicht der Adapter, den ich suche.
Antwort1
Jemand könnte ein Programm vorschlagen. Es ist kein triviales Problem,Also:
- "ANSI-Sequenzen" sind in ECMA-48 standardisiert,
- einige Ihrer Beispiele (wie das Aussehen des Cursors undenter_ca_mode) sind nicht im Standard,
- einige wie dieenter_ca_mode
1049
Code haben Variationen (\E7\E[?47h
). Wenn ein Programm auf eine Terminalbeschreibung angewiesen ist, wird nur eine der Variationen erkannt, - Einige der Sequenzen sind parametrisiert, was bedeutet, dass ein Programm entweder über integrierte Regeln verfügen oder in der Lage sein muss, Terminalfunktionen
\E[%i%p1%d;%p2%dH
in einen regulären Ausdruck umzuwandeln, der mit den Eingaben abgeglichen werden kann.
Wenn daher jemand ein Programm vorschlägt, wird es diese Aspekte wahrscheinlich nicht lösen, sondern lediglich ein Terminalemulator ohne Anzeige sein.
Antwort2
Wenn Sie nur die ANSI-Cursorbewegung wünschen, können Sie einfach einen Interpreter mit dem NPM-Modul erstellenKnoten-Ansiparser. Ich habe dasselbe Modul für meine JavaScript-Bibliothek verwendet:jQuery-Terminal, wo ich ANSI-Escapes und Übertypisierungen (Ausgabe des Man-Befehls) analysiere und verarbeite.
Sie können sich auf GitHub ansehen, wie ich den Parser verwendet habe.unix_formatting.js(die Datei enthält den ANSI-Parser). Sie können versuchen, den Code so zu ändern, dass nur Text verarbeitet wird und die Farben ignoriert werden (die Formatierungssyntax des jQuery-Terminals). Das sollte nicht so schwer sein.
Wenn Sie es schnell haben möchten, können Sie ein Skript erstellen, das nur die Datei verarbeitet und die von jQuery Terminal verwendete Formatierung entfernt. Hier ist ein schneller Hack, der das erledigt (aber Sie sollten wahrscheinlich besser die Datei unix_formatting.js ändern und alles entfernen, was nicht benötigt wird).
Um mit jQuery Terminal zu beginnen, verwenden Sie Folgendes:
mkdir ansi-text
cd ansi-text
npm init -y # you need nodeJS installed
npm install jquery.terminal
Erstellen Sie dann diese Datei im selben Verzeichnis:
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));
});
});
}
Sie können dann ein Testskript erstellen:
test.sh
tput cup 2 3;
echo HELLO;
tput cup 5 20;
echo WORLD;
Und Sie können sehen, dass es funktioniert, indem Sie Folgendes verwenden:
unbuffer ./test.sh | ./ansi-text.js
Ausgabe:
kuba@jcubic:~/projects/jcubic/ansi-text$ unbuffer test.sh | ./ansi-text.js
HELLO
WORLD
kuba@jcubic:~/projects/jcubic/ansi-text$
Durch unbuffer wird das Skript denken, dass es TTY ist (es ist Teil von expect).
Der JS-Code verarbeitet die Breite des Terminals nicht, kann aber problemlos hinzugefügt werden, nachdem Sie ANSI-Escapes umgewandelt haben. Um die Ausgabe aufzuteilen, verwenden Sie: $.terminal.split_equal(string, cols)
Sie können aber wahrscheinlich auch etwas Einfacheres verwenden, da Sie die jQuery-Terminalformatierung nicht verarbeiten müssen, was der Hauptzweck der Funktion ist.