Em printf '%s\t%s\n' foo bar
, printf
produz foo<TAB>bar<LF>
.
f
, o
, b
, a
E r
são caracteres gráficos individuais de largura.
Ao receber esses caracteres, o terminal exibirá um glifo correspondente e moverá o cursor uma coluna para a direita, a menos que já tenha atingido a borda direita da tela (papel nas tele-máquinas de escrever originais), caso em que poderá alimentar uma linha e retorne à borda esquerda da tela (quebra automática) ou apenas descarte o caractere, dependendo do terminal e de como ele foi configurado.
<Tab>
e <LF>
são dois caracteres de controle . <LF>
(aka newline) é o delimitador de linha no texto Unix, mas para terminais, apenas alimenta uma linha (mova o cursor uma posição para baixo). Portanto, o driver do terminal no kernel irá convertê-lo para <CR>
(retornar à borda esquerda da tela), <LF>
(cursor para baixo) ( stty onlcr
geralmente ativado por padrão).
<Tab>
diz ao terminal para mover o cursor até a próxima parada de tabulação (que na maioria dos terminais tem 8 posições à parte, por padrão, mas também pode ser configurada para ser configurada em qualquer lugar) sem preencher a lacuna com espaços em branco.
Portanto, se esses caracteres forem enviados para um terminal com tabulação a cada 8 colunas enquanto o cursor estiver no início de uma linha vazia, isso resultará em:
foo bar
impresso na tela nessa linha. Se eles forem enviados enquanto o cursor estiver na terceira posição em uma linha que contenha xxxxyyyyzzzz
, isso resultará em:
xxfooyyybarz
Em terminais que não oferecem suporte à tabulação, o driver do terminal pode ser configurado para converter essas guias em seqüências de espaços. ( stty tab3
)
O caractere SPC, nas tele-máquinas de escrever originais, moveria o cursor para a direita, enquanto backspace ( \b
) o moveria para a esquerda. Agora, nos terminais modernos, o SPC se move para a direita e também apaga (escreve um caractere de espaço conforme o esperado). Então o pingente de \b
tinha que ser algo mais novo que o ASCII. Na maioria dos terminais modernos, é, na verdade, uma sequência de caracteres: <Esc>
, [
, C
.
Existem mais seqüências de escape para mover os n
caracteres para a esquerda, direita, cima, baixo ou em qualquer posição da tela. Existem outras seqüências de escape para apagar (preencher em branco) partes de linhas ou regiões da tela, etc.
Essas seqüências são geralmente usados por aplicativos visuais como vi
, lynx
, mutt
, dialog
em que o texto é escrito em posições arbitrárias na tela.
Agora, todos os emuladores de terminal X11 e alguns outros não-X11 como o GNU screen
permitem selecionar áreas da tela para copiar e colar. Quando você seleciona uma parte do que vê no vi
editor, não deseja copiar todas as sequências de escape usadas para produzir essa saída. Você deseja selecionar o texto que vê lá.
Por exemplo, se você executar:
printf 'abC\rAC\bB\t\e[C\b\bD\n'
Que simula uma sessão editor onde você entra abC
, volte para o início, substitua ab
com AC
, C
com B
, mover para a próxima parada de tabulação, em seguida, mais uma coluna à direita, em seguida, duas colunas à esquerda, em seguida, digite D
.
Entende:
ABC D
Ou seja, ABC
uma lacuna de 4 colunas e D
.
Se você selecionar com o mouse em xterm
ou putty
, eles serão armazenados na seleção ABC
, 4 caracteres de espaço e D
, não abC<CR>AC<BS>B<Tab><Esc>[C<BS><BS>D
.
O que acaba na seleção é o que foi enviado, printf
mas pós-processado pelo driver do terminal e pelo emulador de terminal.
Para outros tipos de transformação, consulte o <U+0065><U+0301>
( e
seguido de um acento agudo combinado) alterado para <U+00E9>
( é
a forma pré-composta) por xterm
.
Ou echo abc
isso acaba sendo traduzido ABC
pelo driver do terminal antes de ser enviado ao terminal após a stty olcuc
.
Agora, <Tab>
like <LF>
é um daqueles poucos caracteres de controle que, às vezes, são encontrados em arquivos de texto (também <CR>
nos arquivos de texto do MSDOS, e às vezes <FF>
para quebra de página).
Portanto, alguns emuladores de terminal optam por copiá-los quando possível nos buffers de copiar e colar para preservá-los (esse geralmente não é o caso <CR>
nem o caso <LF>
).
Por exemplo, em terminais baseados em VTE como gnome-terminal
, você pode ver que, quando você seleciona a saída printf 'a\tb\n'
em uma linha vazia, gnome-terminal
na verdade armazena a\tb
na seleção X11 em vez de a
7 espaços e b
.
Mas para a saída printf 'a\t\bb\n'
, ele armazena a
, 6 espaços e b
, e por printf 'a\r\tb\n'
, a
, 7 espaços e b
.
Há outros casos em que os terminais tentam copiar a entrada real, como quando você seleciona duas linhas após a execução, printf 'a \nb\n'
onde esse espaço invisível à direita será preservado. Ou, ao selecionar duas linhas, não inclui um caracter LF quando as duas linhas resultam da quebra automática na margem direita.
Agora, se você deseja armazenar a saída printf
no CLIPBOARD X11
, é melhor fazê-lo diretamente, como:
printf 'foo\tbar\n' | xclip -sel c
Observe que quando você cola isso no xterm
ou na maioria dos outros terminais, xterm
na verdade o substitui \n
por \r
porque esse é o caractere xterm
enviado quando você pressiona Enter(e o driver do terminal pode convertê-lo novamente para \n
).