Вопрос или проблема
У меня есть текстовые файлы, которые содержат 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, и выводить текст в ожидаемом формате.