В printf '%s\t%s\n' foo bar
, printf
делает вывод foo<TAB>bar<LF>
.
f
, o
, b
, a
И r
являются одной шириной графических символов.
После получения этих символов терминал отобразит соответствующий глиф и переместит курсор на один столбец вправо, если только он уже не достиг правого края экрана (бумага в оригинальных пишущих машинках)), и в этом случае он может подать строку и вернитесь к левому краю экрана (обтекание) или просто откажитесь от символа в зависимости от терминала и его настройки.
<Tab>
и <LF>
два управляющих символа. <LF>
(aka newline) - это разделитель строк в тексте Unix, но для терминалов он просто подает строку (переместите курсор на одну позицию вниз). Таким образом, драйвер терминала в ядре фактически переведет его в <CR>
(возврат к левому краю экрана), <LF>
(курсор вниз) ( stty onlcr
обычно по умолчанию включен).
<Tab>
говорит терминалу переместить курсор к следующей позиции табуляции (которая на большинстве терминалов по умолчанию разделена на 8 позиций, но также может быть настроена для установки в любом месте) без заполнения пробела.
Поэтому, если эти символы отправляются в терминал с табуляцией через каждые 8 столбцов, а курсор находится в начале пустой строки, это приведет к:
foo bar
напечатан на экране в этой строке. Если они отправляются, когда курсор находится на третьей позиции в строке, которая содержит xxxxyyyyzzzz
, это приведет к:
xxfooyyybarz
На терминалах, которые не поддерживают табулирование, драйвер терминала может быть сконфигурирован для преобразования этих вкладок в последовательности пробелов. ( stty tab3
).
Символ SPC в оригинальных пишущих машинках будет перемещать курсор вправо, а backspace ( \b
) - влево. Теперь в современных терминалах SPC перемещается вправо и также стирает (пишет символ пробела, как вы ожидаете). Так что подвеска \b
должна была быть чем-то более новым, чем ASCII. На большинстве современных терминалов, на самом деле это последовательность символов: <Esc>
, [
, C
.
Есть больше escape-последовательностей для перемещения n
символов влево, вправо, вверх, вниз или в любую позицию на экране. Существуют и другие escape-последовательности для удаления (заполнения пустыми) частей линий или областей экрана и т. Д.
Эти последовательности , как правило , используется визуальными приложениями , таких как vi
, lynx
, mutt
, dialog
где текст написан в произвольных позициях на экране.
Теперь все эмуляторы терминала X11 и несколько других эмуляторов, отличных от X11, таких как GNU, screen
позволяют выбирать области экрана для копирования и вставки. Когда вы выбираете часть того, что видите в vi
редакторе, вы не хотите копировать все escape-последовательности, которые использовались для создания этого вывода. Вы хотите выбрать текст, который вы видите там.
Например, если вы запустите:
printf 'abC\rAC\bB\t\e[C\b\bD\n'
Что имитирует редактор сеанса , когда вы входите abC
, вернуться к началу, замените ab
с AC
, C
с B
, перейти на следующую позицию табуляции, а затем еще один столбец вправо, затем два столбца слева, а затем ввести D
.
Вы видите:
ABC D
То есть ABC
пробел в 4 столбца и D
.
Если вы выберите это с помощью мыши в xterm
или putty
, они будут хранить в выделении ABC
, 4 пробела и D
, не abC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D
.
То, что заканчивается в выборе, - это то, что было отправлено, printf
но обработано как драйвером терминала, так и эмулятором терминала.
Для других видов трансформации см. <U+0065><U+0301>
(С e
последующим комбинированным острым акцентом), измененным на <U+00E9>
( é
предварительно составленная форма) xterm
.
Или echo abc
это заканчивается переводом ABC
на драйвер терминала перед отправкой на терминал после a stty olcuc
.
Теперь, <Tab>
похоже <LF>
, один из тех немногих управляющих символов, которые иногда встречаются в текстовых файлах (также <CR>
в текстовых файлах MSDOS, а иногда и <FF>
для разрыва страницы).
Поэтому некоторые эмуляторы терминалов предпочитают копировать их, когда это возможно, в буферах копирования и вставки, чтобы сохранить их (как правило, это не так и <CR>
не <LF>
так).
Например, в терминалах на основе VTE, таких как gnome-terminal
, вы можете видеть, что, когда вы выбираете вывод в printf 'a\tb\n'
пустой строке, gnome-terminal
фактически сохраняет a\tb
в выборе X11 вместо a
7 пробелов и b
.
Но для вывода printf 'a\t\bb\n'
, он хранит a
, 6 мест и b
, и для printf 'a\r\tb\n'
, a
, 7 пространств и b
.
Есть и другие случаи, когда терминалы будут пытаться скопировать фактический ввод, например, когда вы выберете две строки после запуска, printf 'a \nb\n'
где это невидимое конечное пространство будет сохранено. Или при выборе двух строк не включает в себя символ НЧ, когда две строки являются результатом переноса с правого поля.
Теперь, если вы хотите сохранить выходные данные printf
в CLIPBOARD X11
select, лучше всего сделать это напрямую так:
printf 'foo\tbar\n' | xclip -sel c
Обратите внимание , что при вставке , что xterm
и большинство других терминалов, xterm
фактически заменяет , что \n
с , \r
потому что это символ xterm
посылает при нажатии Enter(и драйвер терминала может перевести его обратно \n
).