Я пытаюсь напечатать две строки, разделенные вкладкой. Я пытался:
echo -e 'foo\tbar'
printf '%s\t%s\n' foo bar
Они оба печатают:
foo bar
Где пробел между ними на самом деле 5 пробелов (согласно выбору вывода с помощью мыши в Putty).
Я также пытался использовать CTRL + V и нажимать клавишу TAB при наборе команды, с тем же результатом.
Как правильно заставить вкладку печататься как вкладку, чтобы я мог выбрать вывод и скопировать его в другое место с вкладками?
И второстепенный вопрос: почему bash расширяет табуляции в пробелы?
Обновление : По-видимому, это проблема Putty: /superuser/656838/how-to-make-putty-display-tabs-within-a-file-instead-of-changing-them-to -пространствами
bash
putty
whitespace
tabs
Асу
источник
источник
printf '%s\\t%s\n' foo bar
foo\tbar
...$'\t'
как табулятор. Таким образом, вы всегда можете объединить строки, подобные этой, например, как присваивание:v='This is'$'\t''a test'
и напечатать это буквально, например,printf '%s' "$v"
Ответы:
Как сказал ilkkachu, проблема связана не с bash, а с эмулятором терминала, который преобразует табуляцию в пробелы на выходе.
При проверке разных терминалов, putty, xterm и konsole конвертируют вкладки в пробелы, а urxvt и gnome-Terminal - нет. Итак, другое решение заключается в переключении терминалов.
источник
stty tab3
.Нет, это не так. Не в выводе
echo
илиprintf
.Это другая проблема. Дело не в оболочке, а в эмуляторе терминала, который преобразует вкладки в пробелы на выходе. Многие, но не все, делают это.
Может быть проще перенаправить вывод с вкладками в файл и скопировать его оттуда, либо использовать
unexpand
в выводе для преобразования пробелов во вкладки. (Хотя он также не может знать, какие пробелы были с самого начала вкладками, и, если возможно, преобразует их все во вкладки.) Это, конечно, будет зависеть от того, что именно нужно делать с выводом.источник
В
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 столбцов, а курсор находится в начале пустой строки, это приведет к:
напечатан на экране в этой строке. Если они отправляются, когда курсор находится на третьей позиции в строке, которая содержит
xxxxyyyyzzzz
, это приведет к:На терминалах, которые не поддерживают табулирование, драйвер терминала может быть сконфигурирован для преобразования этих вкладок в последовательности пробелов. (
stty tab3
).Символ SPC в оригинальных пишущих машинках будет перемещать курсор вправо, а backspace (
\b
) - влево. Теперь в современных терминалах SPC перемещается вправо и также стирает (пишет символ пробела, как вы ожидаете). Так что подвеска\b
должна была быть чем-то более новым, чем ASCII. На большинстве современных терминалов, на самом деле это последовательность символов:<Esc>
,[
,C
.Есть больше escape-последовательностей для перемещения
n
символов влево, вправо, вверх, вниз или в любую позицию на экране. Существуют и другие escape-последовательности для удаления (заполнения пустыми) частей линий или областей экрана и т. Д.Эти последовательности , как правило , используется визуальными приложениями , таких как
vi
,lynx
,mutt
,dialog
где текст написан в произвольных позициях на экране.Теперь все эмуляторы терминала X11 и несколько других эмуляторов, отличных от X11, таких как GNU,
screen
позволяют выбирать области экрана для копирования и вставки. Когда вы выбираете часть того, что видите вvi
редакторе, вы не хотите копировать все escape-последовательности, которые использовались для создания этого вывода. Вы хотите выбрать текст, который вы видите там.Например, если вы запустите:
Что имитирует редактор сеанса , когда вы входите
abC
, вернуться к началу, заменитеab
сAC
,C
сB
, перейти на следующую позицию табуляции, а затем еще один столбец вправо, затем два столбца слева, а затем ввести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
на драйвер терминала перед отправкой на терминал после astty 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
в CLIPBOARDX11
select, лучше всего сделать это напрямую так:Обратите внимание , что при вставке , что
xterm
и большинство других терминалов,xterm
фактически заменяет , что\n
с ,\r
потому что это символxterm
посылает при нажатии Enter(и драйвер терминала может перевести его обратно\n
).источник
X11
- это то , что обрабатывает выбор копирования-вставки в эмуляторах терминала, таких какxterm
илиputty
в Unix. Другие эмуляторы терминала может есть у них собственный механизм копирования и вставки и способы хранения произвольного содержания там, вродеreadbuf
иregister
команды в окне GNU.