Как удалить ^ [и все escape-последовательности в файле с помощью сценариев linux shell
Мы хотим удалить ^[
и все escape-последовательности.
sed не работает и дает нам эту ошибку:
$ sed 's/^[//g' oldfile > newfile; mv newfile oldfile;
sed: -e expression #1, char 7: unterminated `s' command
$ sed -i '' -e 's/^[//g' somefile
sed: -e expression #1, char 7: unterminated `s' command
Ответы
Ответ 1
Вы ищете ансифильтр?
Вы можете сделать две вещи: ввести буквальный escape (в bash :)
Использование ввода с клавиатуры:
sed 's/Ctrl-vEsc//g'
альтернативно
sed 's/Ctrl-vCtrl-[//g'
Или вы можете использовать экранирование символов:
sed 's/\x1b//g'
или для всех управляющих символов:
sed 's/[\x01-\x1F\x7F]//g' # NOTE: zaps TAB character too!
Ответ 2
Я справился со следующим для моих целей, но это не включает все возможные выходы ANSI:
sed -r s/\x1b\[[0-9;]*m?//g
Это удаляет m
команд, но для всех выходов (как прокомментировал @lethalman) используйте:
sed -r s/\x1b\[[^@-~]*[@-~]//g
Также смотрите " Регулярное выражение Python для соответствия escape-последовательностей VT100 ".
Существует также таблица общих escape-последовательностей.
Ответ 3
commandlinefu дает правильный ответ, который отбрасывает цвета ANSI, а также команды перемещения:
sed "s,\x1B\[[0-9;]*[a-zA-Z],,g"
Ответ 4
Команда ansi2txt (часть пакета kbtin), похоже, отлично выполняет работу над Ubuntu.
Ответ 5
Я наткнулся на этот пост, когда искал способ убрать лишнее форматирование с man-страниц. это сделал ansifilter, но это было далеко от желаемого результата (например, все ранее выделенные жирным шрифтом символы были дублированы, например, SSYYNNOOPPSSIISS
).
Для этой задачи правильная команда будет col -bx
, например:
groff -man -Tascii fopen.3 | col -bx > fopen.3.txt
(источник)
Ответ 6
Просто примечание; скажем, у вас есть такой файл (такие окончания строк генерируются git
удаленными отчетами):
echo -e "remote: * 27625a8 (HEAD, master) 1st git commit\x1b[K
remote: \x1b[K
remote: \x1b[K
remote: \x1b[K
remote: \x1b[K
remote: \x1b[K
remote: Current branch master is up to date.\x1b[K" > chartest.txt
В двоичном формате это выглядит так:
$ cat chartest.txt | hexdump -C
00000000 72 65 6d 6f 74 65 3a 20 2a 20 32 37 36 32 35 61 |remote: * 27625a|
00000010 38 20 28 48 45 41 44 2c 20 6d 61 73 74 65 72 29 |8 (HEAD, master)|
00000020 20 31 73 74 20 67 69 74 20 63 6f 6d 6d 69 74 1b | 1st git commit.|
00000030 5b 4b 0a 72 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 |[K.remote: .[K.r|
00000040 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 65 6d 6f 74 |emote: .[K.remot|
00000050 65 3a 20 1b 5b 4b 0a 72 65 6d 6f 74 65 3a 20 1b |e: .[K.remote: .|
00000060 5b 4b 0a 72 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 |[K.remote: .[K.r|
00000070 65 6d 6f 74 65 3a 20 43 75 72 72 65 6e 74 20 62 |emote: Current b|
00000080 72 61 6e 63 68 20 6d 61 73 74 65 72 20 69 73 20 |ranch master is |
00000090 75 70 20 74 6f 20 64 61 74 65 2e 1b 5b 4b 0a |up to date..[K.|
0000009f
Видно, что git
здесь добавляет последовательность 0x1b
0x5b
0x4b
до окончания строки (0x0a
).
Обратите внимание, что - если вы можете сопоставить 0x1b
с литеральным форматом \x1b
в sed, вы НЕ МОЖЕТЕ сделать то же самое для 0x5b
, который представляет собой квадратную скобку слева [
:
$ cat chartest.txt | sed 's/\x1b\x5b//g' | hexdump -C
sed: -e expression #1, char 13: Invalid regular expression
Вы можете подумать, что вы можете избежать представления с дополнительной обратной косой чертой \
- которая заканчивается как \\x5b
; но в то время как это "проходит" - оно не соответствует чему-либо, как предполагалось:
$ cat chartest.txt | sed 's/\x1b\\x5b//g' | hexdump -C
00000000 72 65 6d 6f 74 65 3a 20 2a 20 32 37 36 32 35 61 |remote: * 27625a|
00000010 38 20 28 48 45 41 44 2c 20 6d 61 73 74 65 72 29 |8 (HEAD, master)|
00000020 20 31 73 74 20 67 69 74 20 63 6f 6d 6d 69 74 1b | 1st git commit.|
00000030 5b 4b 0a 72 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 |[K.remote: .[K.r|
00000040 65 6d 6f 74 65 3a 20 1b 5b 4b 0a 72 65 6d 6f 74 |emote: .[K.remot|
...
Итак, если вы хотите совместить этот символ, видимо, вы должны записать его как экранированную левую квадратную скобку, то есть \[
- остальные значения могут быть введены с экранированным обозначением \x
:
$ cat chartest.txt | sed 's/\x1b\[\x4b//g' | hexdump -C
00000000 72 65 6d 6f 74 65 3a 20 2a 20 32 37 36 32 35 61 |remote: * 27625a|
00000010 38 20 28 48 45 41 44 2c 20 6d 61 73 74 65 72 29 |8 (HEAD, master)|
00000020 20 31 73 74 20 67 69 74 20 63 6f 6d 6d 69 74 0a | 1st git commit.|
00000030 72 65 6d 6f 74 65 3a 20 0a 72 65 6d 6f 74 65 3a |remote: .remote:|
00000040 20 0a 72 65 6d 6f 74 65 3a 20 0a 72 65 6d 6f 74 | .remote: .remot|
00000050 65 3a 20 0a 72 65 6d 6f 74 65 3a 20 0a 72 65 6d |e: .remote: .rem|
00000060 6f 74 65 3a 20 43 75 72 72 65 6e 74 20 62 72 61 |ote: Current bra|
00000070 6e 63 68 20 6d 61 73 74 65 72 20 69 73 20 75 70 |nch master is up|
00000080 20 74 6f 20 64 61 74 65 2e 0a | to date..|
0000008a
Ответ 7
Я построил vtclean для этого. Он разбивает escape-последовательности, используя эти регулярные выражения в порядке (объясняется в regex.txt):
// handles long-form RGB codes
^\033](\d+);([^\033]+)\033\\
// excludes non-movement/color codes
^\033(\[[^[email protected]\?]+|[\(\)]).
// parses movement and color codes
^\033([\[\]]([\d\?]+)?(;[\d\?]+)*)?(.)`)
Кроме того, выполняется базовая эмуляция правого редактирования, поэтому анализируются backspace и другие символы перемещения (например, клавиша со стрелкой влево).
Ответ 8
Вы можете удалить все непечатаемые символы с помощью этого:
sed 's/[^[:print:]]//g'
Ответ 9
У меня недостаточно репутации, чтобы добавить комментарий к ответу Люка Х., но я хотел бы поделиться регулярным выражением, которое я использовал для устранения всех ASCII Escape-последовательностей.
sed -r 's~\x01?(\x1B\(B)?\x1B\[([0-9;]*)?[JKmsu]\x02?~~g'
Ответ 10
Ответ Тома Хейла оставил нежелательные коды, но послужил хорошей основой для работы. Добавление дополнительной фильтрации убрало остатки нежелательных кодов:
sed -e "s,^[[[(][0-9;?]*[a-zA-Z],,g" \
-e "s/^[[[][0-9][0-9]*[@]//" \
-e "s/^[[=0-9]<[^>]*>//" \
-e "s/^[[)][0-9]//" \
-e "s/.^H//g" \
-e "s/^M//g" \
-e "s/^^H//" \
file.dirty > file.clean
Так как это было сделано для не-GNU версии sed, где вы видите ^[
, ^H
и ^M
, я использовал Ctrl- V <Esc>, Ctrl- V Ctrl- H и Ctrl- V Ctrl- M соответственно. ^>
Буквально карат (^) и символ больше, чем Ctrl- <.
TERM = xterm использовался в то время.
Ответ 11
Фрагмент bash, который я использовал для удаления (по крайней мере, некоторых) цветов ANSI:
shopt -s extglob
while IFS='' read -r line; do
echo "${line//$'\x1b'\[*([0-9;])[Km]/}"
done