Символ разделителя единиц ASCII (ASCII 31, восьмеричное 37) отображается в Vim как a ^_
. Но если я печатаю тот же файл в терминал, символ становится невидимым. Это приводит к слипанию полей в строке:
# In Vim and less:
first field^_second field^_last field
# cat the same file to terminal:
cat delim.txt
first fieldsecond fieldlast field
# print 2nd field with awk
cat delim.txt | awk 'BEGIN {FS = "\037"} {print $2}'
second field
Я полагаю, я могу сделать разделитель модулей видимым с помощью cat -v:
cat -v delim.txt
first field^_second field^_last field
Но это довольно громоздко. Почему разделитель модулей не имеет видимого представления при выводе на стандартный вывод в оболочке Bash? Я даже не могу правильно скопировать и вставить вывод оболочки; разделитель блоков теряется в процессе.
Ответы:
Символ separator (
US
), также известный какIS1
, находится вcntrl
классе символов и не находится вprint
классе символов. Это управляющий символ, предназначенный для организации текста в группы, для программ, которые предназначены для использования этой информации . В общем, непечатные символы, вероятно, будут интерпретироваться и отображаться по-разному в разных программах или средах.Причина, по которой вы видите его
^_
в Vim, заключается в том, что Vim - интерактивный редактор. Он может свободно отображать непечатаемые символы по своему усмотрению, если на диск записан правильный двоичный символ.Вы не можете получить такое же поведение в оболочке, потому что программы оболочки Unix написаны для работы и передачи простого текста друг другу. Когда вы
cat
файл, текст, который записывается в терминал, должен быть тем, что на самом деле находится в файле.Так что это оставляет терминальному устройству для интерпретации символа. И получается, что некоторые эмуляторы терминала делают визуализации
US
персонажа в отличие от других. Вgnome-terminal
(или любомvte
терминале на основе) символ будет отображаться как поле, содержащее шестнадцатеричный код001F
. Вxterm
илиrxvt
, персонаж действительно невидим.источник
US
что совершенно невидим. Когда я вставляю этот символ в терминал сCtrl+/
помощью (подтверждено через<C-v><C-/>
), он удаляет непредсказуемое количество текста в строке. Я не до конца понимаю его поведение, но, похоже, он в основном имеет какой-то эффект «обратной табуляции», когда вместо вставки нескольких пробелов он удаляет несколько символов, но иногда он случайным образом вставляет текст, поэтому это сбивает с толку ,Разделитель единиц находится в диапазоне ASCII управляющих символов и поэтому не имеет (или не должен обычно) иметь визуальное представление.
Vim и некоторые другие редакторы отображают их, поэтому вы можете редактировать их. Как вы заметили,
cat -v
отображает это тоже. Страница man показывает, что-v
это краткая форма--show-nonprinting
, которая заставляет ее заменить непечатаемые символы печатным представлением, которое не является исходным содержимым файла и, следовательно, может вызвать проблемы, если на самом деле выходные данные принадлежат другой программе. ,Представление, которое вы видите, уже намекает на то, что это управляющий символ: символ, начинающийся с буквы «a»,
^
является обычной записью для Ctrlсимвола +, который является комбинацией клавиш, которая создает этот символ в терминале. Ctrl+ _позволит вам ввести разделитель единиц в vim, например. Но другой редактор или программа просмотра GUI может отображать шестнадцатеричный код, заполнитель или что-то совершенно другоеПоскольку ваш терминал не печатает управляющие символы, он также не копируется при выделении текста (исключение составляют пробельные символы, такие как символ новой строки и табуляция, которые также являются управляющими символами). Другим примером управляющих символов в терминале, которые обычно игнорируются при копировании, являются цветовые коды, которые представляют собой
ESC
символ, за которым следует код для раскрашивания текста.Таким образом, для отображения символов на вашем терминале нет другого способа, кроме как использовать программу, которая заменяет разделитель единиц на какой-либо печатный символ.
источник
Немного на полях других (очень хороших) ответов, если вы хотите изменить только управляющий символ
^_
при отображении содержимого файла, вы можете захотеть транслитерировать его с помощьюtr
утилиты (и немного синтаксиса, совместимого с bash) :Если вам нужно заменить этот управляющий символ его «расширенной» формой, вам нужно
sed
вместо этого:Обратите внимание на синтаксис
$'\cX'
: этот синтаксис информирует вашу (bash-совместимую оболочку) о замене соответствующего управляющего символа. См. Википедию для получения списка псевдонимов управляющих символов с использованием «каретки». Если вам не нравится этот синтаксис, вы можете использовать восьмеричное$'\037'
$'\x1f'
вместо этого или шестнадцатеричные обозначения.источник