Рассмотрите следующее:
$ cat -A input.txt
Hello^IWorld$
newline$
Здесь, cat -A
берет фактические новые строки и вкладки, т.е. реальные символы, и преобразовывает их в представления.
Существует ли оболочка путь или приложение командной строки в репозиториях Ubuntu, которые позволили бы брать представления непечатных символов и произвели бы действительные значения?
В некотором смысле я спрашиваю, существует ли что-то аналогичное $'Hello\tWorld\nnewline\n'
, кроме вместо строк C-quoted, я хочу использование "заключенные в кавычки из оболочки" строки.
Ну, Python к спасению!
Проверьте эту остроту, которая читает из STDIN и печатает к STDOUT, обрабатывая все возможные "Escape каре" / "коды C0" (как ^I
) и индикаторы конца строки ($
):
python3 -c 'import sys,re;print(re.sub(r"\^([A-Z?@[\\\]^_])",lambda m:chr((ord(m.group(1))-64)&127),sys.stdin.read().replace("$\n","\n")))'
На самом деле это оба совместимо с python
(2) и python3
. Вот более длинное, больше читаемой версии, делающей в основном то же:
#!/usr/bin/env python3
import sys, re
# read everything from stdin and remove line-end indicators
s = sys.stdin.read().replace("$\n", "\n"))
# replace caret escapes like ^I or ^M and output to stdout
print(re.sub(r"\^([A-Z?@[\\\]^_])", lambda m: chr((ord(m.group(1)) - 64) & 127), s)
Так, сначала мы удаляем индикаторы конца строки $
.
Второй мы используем образец регулярного выражения \^([A-Z?@[\\\]^_])
найти все допустимые символы после каре и заменить и корректным незавершенным символом, согласно Википедии на нотации Каре и кодами управления C0. Отметьте как только прописные буквы A
-Z
или один из ?@[\]^_
имейте особое значение.
Теперь для невыхода из такого кода C0 мы занимаем позицию в алфавите символа, следующего за каре (найденный в m.group(1)
), например, "A" равняется 1, "B" равняется 2 и так далее. Это равно его значению ASCII минус код ASCII "A" плюс один, который составляет эти-64, который также объясняет, например, (ASCII 64), являющийся 0 или" [" (ASCII 91), являющийся ESC (ASCII 27). Мы делаем двоичную операцию И на этом числе с 127, чтобы только рассмотреть первые 7 битов информации, так, чтобы, например,"?" (ASCII 63 == 64-1) повторяется к 127, представляя символ DEL.
Наконец после того, как все эти очень сложные вычисления сделаны, мы просто печатаем получившую строку к STDOUT снова.