Как напечатать строки, разделенные табулятором, в bash?

Я мог воспроизвести проблему в своей системе.
Ваша основная проблема - ограничения ACL вашего хоста.
По этой причине измените атрибуты ACL пользователя libvirt-qemu :

sudo setfacl -R -m u:libvirt-qemu:rwx /media/cl

Измените настройки режима для Файловая система / хост из Сквозной в Сопоставленный .


Почему? Вот почему:

Ваша гостевая система работает как пользователь libvirt-qemu , и ваши настройки ACL ограничивают права этого пользователя.

user:libvirt-qemu:--x

Правильный вывод getfacl должен быть:

user:libvirt-qemu:rwx
9
16.12.2018, 16:10
3 ответа

Как сказал ilkkachu, это проблема не bash, а эмулятора терминала, который на выходе преобразует табуляцию в пробелы.

Проверка различных терминалов: putty, xterm и konsole преобразуют табуляцию в пробелы, а терминал urxvt и gnome -— нет. Итак, еще одно решение - переключить терминалы.

9
27.01.2020, 20:04

the whitespace between the two is actually 5 spaces.

Нет, это не так. Не в выводе echoили printf.

$ echo -e 'foo\tbar' | od -c
0000000   f   o   o  \t   b   a   r  \n
0000010

What is the correct way to force tab being printed as tab, so I can select the output and copy it to somewhere else, with tabs?

Это другой вопрос. Дело не в оболочке, а в эмуляторе терминала, который на выходе преобразует табы в пробелы. Многие, но не все так делают.

Возможно, будет проще перенаправить вывод с табуляциями в файл и скопировать его оттуда или использовать unexpandна выходе для преобразования пробелов в табуляции. (Хотя он также не может знать, какие пробелы были табуляциями с самого начала, и, если возможно, преобразует все это во табуляции. )Это, конечно, будет зависеть от того, что именно вам нужно сделать с выводом.

16
27.01.2020, 20:04

В printf '%s\t%s\n' foo bar, printfвыводит foo<TAB>bar<LF>.

f, o, b, aи rявляются графическими символами одинарной ширины -.

При получении этих символов терминал отобразит соответствующий глиф и переместит курсор на одну колонку вправо, если только он еще не достиг правого края экрана (бумага в оригинальных теле -пишущих машинках )), в этом случае он может пропустить строку и вернуться к левому краю экрана (, обернуть )или просто отбросить символ в зависимости от терминала и его конфигурации.

<Tab>и <LF>— это два управляющих символа.<LF>(или новая строка )— это разделитель строк в тексте Unix,но для терминалов он просто передает строку (перемещает курсор на одну позицию вниз ). Таким образом, драйвер терминала в ядре фактически переведет его в<CR>(возврат к левому краю экрана ),<LF>(курсор вниз)(stty onlcrобычно по умолчанию ).

<Tab>указывает терминалу переместить курсор на следующую позицию табуляции (, которая на большинстве терминалов по умолчанию находится на расстоянии 8 позиций друг от друга, но также может быть настроена для установки в любом месте )без заполнения пробела пробелами.

Таким образом, если эти символы отправляются на терминал с позициями табуляции каждые 8 ​​столбцов, когда курсор находится в начале пустой строки, это приведет к:

foo     bar

напечатано на экране в этой строке. Если они отправляются, когда курсор находится на третьей позиции в строке, содержащей xxxxyyyyzzzz, это приведет к:

xxfooyyybarz

На терминалах, не поддерживающих табуляцию, драйвер терминала можно настроить для преобразования этих вкладок в последовательности пробелов.(stty tab3).

Символ SPC в оригинальных пишущих машинках теле -перемещал курсор вправо, а символ возврата(\b)перемещал его влево. Теперь в современных терминалах SPC перемещается вправо, а также стирает (записывает пробел, как и следовало ожидать ). Таким образом, подвеска \bдолжна была быть чем-то новее, чем ASCII. На большинстве современных терминалов это последовательность символов :<Esc>, [, C.

Есть дополнительные управляющие последовательности для перемещения nсимволов влево, вправо, вверх, вниз или в любую позицию на экране. Существуют и другие управляющие последовательности для стирания (заполнения пустыми )частями строк или областей экрана и т. д.

Эти последовательности обычно используются визуальными приложениями, такими как 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драйвером терминала перед отправкой на терминал после 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', где этот невидимый конечный пробел будет сохранен. Или при выборе двух строк не включает символ LF, когда две строки являются результатом переноса на правом поле.

Теперь, если вы хотите сохранить вывод printfв буфер обмена X11, лучше всего сделать это напрямую, как с:

printf 'foo\tbar\n' | xclip -sel c

Обратите внимание, что когда вы вставляете это в xtermили большинство других терминалов, xtermфактически заменяет это \nна \r, потому что это символ xterm, который отправляется, когда вы нажимаете Enter(и драйвер терминала может преобразовать его обратно в \n).

5
27.01.2020, 20:04

Теги

Похожие вопросы