Estou tentando imprimir duas seqüências de caracteres separadas por um TAB. Eu tentei:
echo -e 'foo\tbar'
printf '%s\t%s\n' foo bar
Ambos imprimem:
foo bar
Onde o espaço em branco entre os dois é na verdade 5 espaços (conforme a seleção da saída com o mouse em Putty).
Também tentei usar CTRL + V e pressionar TAB ao digitar o comando, com o mesmo resultado.
Qual é a maneira correta de forçar a impressão de uma guia como guia, para que eu possa selecionar a saída e copiá-la para outro lugar, com guias?
E a questão secundária: por que o bash está expandindo as guias em espaços?
Atualização : Aparentemente, este é um problema do Putty: /superuser/656838/how-to-make-putty-display-tabs-within-a-file-instead-of-changing-them-to -spaces
bash
putty
whitespace
tabs
Asu
fonte
fonte
printf '%s\\t%s\n' foo bar
foo\tbar
...$'\t'
como tabulador. Assim, você sempre pode concatenar seqüências de caracteres como esta - por exemplo, como atribuição:v='This is'$'\t''a test'
e imprimi-la literalmente, por exemploprintf '%s' "$v"
Respostas:
Como o ilkkachu disse, esse não é um problema do bash, mas do emulador de terminal que converte abas em espaços na saída.
A verificação de diferentes terminais, putty, xterm e konsole converte guias em espaços, enquanto urxvt e gnome-terminal não. Portanto, outra solução é trocar de terminal.
fonte
stty tab3
.Não, não é. Não está na saída de
echo
ouprintf
.Esta é uma questão diferente. Não se trata do shell, mas do emulador de terminal, que converte as guias em espaços na saída. Muitos, mas nem todos fazem isso.
Pode ser mais fácil redirecionar a saída com guias para um arquivo e copiá-la a partir daí, ou usar
unexpand
a saída para converter espaços em guias. (Embora também não possa saber em que espaço em branco eram guias, e converter tudo em guias, se possível.) Isso obviamente dependeria do que exatamente você precisa fazer com a saída.fonte
Em
printf '%s\t%s\n' foo bar
,printf
produzfoo<TAB>bar<LF>
.f
,o
,b
,a
Er
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:
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: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ê novi
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:
Que simula uma sessão editor onde você entra
abC
, volte para o início, substituaab
comAC
,C
comB
, mover para a próxima parada de tabulação, em seguida, mais uma coluna à direita, em seguida, duas colunas à esquerda, em seguida, digiteD
.Entende:
Ou seja,
ABC
uma lacuna de 4 colunas eD
.Se você selecionar com o mouse em
xterm
ouputty
, eles serão armazenados na seleçãoABC
, 4 caracteres de espaço eD
, nãoabC<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) porxterm
.Ou
echo abc
isso acaba sendo traduzidoABC
pelo driver do terminal antes de ser enviado ao terminal após astty 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ídaprintf 'a\tb\n'
em uma linha vazia,gnome-terminal
na verdade armazenaa\tb
na seleção X11 em vez dea
7 espaços eb
.Mas para a saída
printf 'a\t\bb\n'
, ele armazenaa
, 6 espaços eb
, e porprintf 'a\r\tb\n'
,a
, 7 espaços eb
.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 CLIPBOARDX11
, é melhor fazê-lo diretamente, como: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 caracterexterm
enviado quando você pressiona Enter(e o driver do terminal pode convertê-lo novamente para\n
).fonte
X11
é o que lida com a seleção copiar e colar em emuladores de terminal comoxterm
ouputty
no Unix. Outros emuladores de terminal podem ter seu próprio mecanismo de copiar e colar e maneiras de armazenar conteúdo arbitrário, como os comandosreadbuf
eregister
na tela do GNU.