Как я могу передать текст, который содержит ANSI-символы перемещения ESC[xC и ESC[xD, и отформатировать текст соответствующим образом?

Вопрос или проблема

У меня есть текстовые файлы, которые содержат ANSI-коды движения ESC[xC и ESC[xD. Я хочу отфильтровать их, но чтобы каждая строка выводилась с учетом этих кодов.

Рассмотрим строку:

this cat is greenESC[12DdogESC[4Cwhite

Я хотел бы получить на выходе:

this dog is white

Выше ESC означает код эскейпа \0x1b (или \033).

Я уверен, что есть лучший способ (и я уверен, что есть и лучший Perl), но это, кажется, срабатывает:

perl -M5';$e="\x1b";' -lne 'chomp;if(/$e\[\d+[CD]/){$ns="";$p=0;while(/$e\[(\d+)([CD])/g){if(!$ns){$ns=$`;$p=length($ns)}$p+=($2eq"C"?+$1:-$1);($a=$'"'"')=~s/(^[^$e]+).*/$1/;if($a=~/^[^$e]/){substr($ns,$p,length($a),$a);$p+=length($a)}}print $ns}else{print $_}'

Использование ANSI-C кавычек (bash)

$ string=$'this cat is green\e[12Ddog\e[4Cwhite'
$ echo "$string"
this dog is white

Объяснение: синтаксис $'...' является ANSI-C Кавычками, который разворачивает управляющие последовательности в строке (вы также можете использовать \033 — мне просто больше нравится \e). Это работает в случаях, когда текст, хранящийся в переменной, уже имеет интерпретируемые управляющие последовательности.

Использование расширения параметров оболочки (bash)

$ string='this cat is green\e[12Ddog\e[4Cwhite'
$ echo "${string@E}"
this dog is white

Объяснение: ${variable@E} синтаксис разворачивает последовательность эскейпа обратной косой черты в variable.

С более старыми версиями bash

Эти первые два метода работают для меня в bash 5.2.26, но если у вас более старая версия, возможно, вам придется сделать это с помощью printf:

$ string='this cat is green\033[12Ddog\033[4Cwhite\n'
$ echo "$string" | while read -r x; do printf "%b" "$x"; done
this dog is white

Объяснение:

  • -r отключает интерпретацию обратной косой черты для read,
  • "%b" включает интерпретацию обратной косой черты для printf.

Ответ или решение

Как обрабатывать текст и удалять управляющие символы ANSI в bash

Работа с текстом, содержащим управляющие символы ANSI, может быть сложной задачей, особенно когда требуется учитывать их влияние на формат вывода. В данной статье мы подробно рассмотрим, как корректно обработать текст с управляющими символами ESC[xC (перемещение вправо) и ESC[xD (перемещение влево), полностью удаляя эти символы и выводя текст в ожидаемом формате.

Контекст задачи

На примере строки:

this cat is greenESC[12DdogESC[4Cwhite

необходимо получить следующий вывод:

this dog is white

Где управляющий символ ESC обозначает код \0x1b или \033.

Подходы к решению

Существует несколько подходов к обработке строк с управляющими символами ANSI, каждый из которых имеет свои особенности.

1. Использование Perl

Первая и, возможно, наиболее мощная техника – это использование Perl для обработки строки. Вот пример команды, выполняемой в терминале:

perl -M5';$e="\x1b";' -lne 'chomp;if(/$e\[\d+[CD]/){$ns="";$p=0;while(/$e\[(\d+)([CD])/g){if(!$ns){$ns=$`;$p=length($ns)}$p+=($2eq"C"?+$1:-$1);($a=$'"'"')=~s/(^[^$e]+).*/$1/;if($a=~/^[^$e]/){substr($ns,$p,length($a),$a);$p+=length($a)}}print $ns}else{print $_}'

В этом решении:

  • Мы ищем все вхождения управляющих символов.
  • Рассчитываем, как именно они изменяют положение курсора.
  • Удаляем лишний текст, основываясь на результирующей позиции.
2. Использование анси-цитирования в bash

Альтернативный способ, предлагающий простоту и удобство, это использование анси-цитирования:

string=$'this cat is green\e[12Ddog\e[4Cwhite'
echo "$string"

Этот метод позволяет интерпретировать управляющие символы непосредственно в строке, позволяя выводить текст в желаемом формате.

3. Расширение параметров оболочки в bash

Другой способ заключается в использовании функции расширения параметров оболочки:

string='this cat is green\e[12Ddog\e[4Cwhite'
echo "${string@E}"

Этот метод работает, если вы используете более новые версии bash и позволяет избавиться от управляющих символов.

4. Использование printf

Если ваша версия bash старая и не поддерживает предыдущие методы, вы можете воспользоваться командой printf:

string='this cat is green\033[12Ddog\033[4Cwhite\n'
echo "$string" | while read -r x; do printf "%b" "$x"; done

В этом варианте:

  • Флаг -r для read отключает интерпретацию символа обратного слэша.
  • %b в printf позволяет интерпретировать управляющие последовательности.

Заключение

Обработка текста с управляющими ANSI символами может быть выполнена различными способами в зависимости от ваших потребностей и окружения. Каждый из методов имеет свои преимущества: от простоты реализации до гибкости и мощи, предлагаемых Perl. Выбор подхода зависит от вашего опыта и требований конкретной задачи.

SEO Оптимизация

Ключевые слова: обработка текста, ANSI коды, bash, Perl, управляющие символы, текстовые файлы.

Учитывая изложенные подходы и примеры, вы сможете эффективно решать задачи, связанные с обработкой управляющих символов ANSI, и выводить текст в ожидаемом формате.

Оцените материал
Добавить комментарий

Капча загружается...