В 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 вместо a7 пробелов и b.
Но для вывода printf 'a\t\bb\n', он хранит a, 6 мест и b, и для printf 'a\r\tb\n', a, 7 пространств и b.
Есть и другие случаи, когда терминалы будут пытаться скопировать фактический ввод, например, когда вы выберете две строки после запуска, printf 'a \nb\n'где это невидимое конечное пространство будет сохранено. Или при выборе двух строк не включает в себя символ НЧ, когда две строки являются результатом переноса с правого поля.
Теперь, если вы хотите сохранить выходные данные printfв CLIPBOARD X11select, лучше всего сделать это напрямую так:
printf 'foo\tbar\n' | xclip -sel c
Обратите внимание , что при вставке , что xtermи большинство других терминалов, xtermфактически заменяет , что \nс , \rпотому что это символ xtermпосылает при нажатии Enter(и драйвер терминала может перевести его обратно \n).