Caracteres da guia Eco no script bash


313

Como ecoar um ou mais caracteres de tabulação usando um script bash? Quando executo esse código

res='       'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

Eu entendi isso

res=[ x] # that is [<space>x]

Respostas:


529
echo -e ' \t '

ecoará 'nova aba do espaço da guia de espaço' ( -esignifica 'habilitar a interpretação de escapes de barra invertida'):

$ echo -e ' \t ' | hexdump -C
00000000  20 09 20 0a                                       | . .|

Obrigado Johannes. Você me ajudou a encontrar esta solução: res = '\ t \ t'x; echo -e '[' $ res ']'
kalyanji 8/02/09

2
Você sabe por echo -eque não funciona no Makefiles?
dma_k

23
Isso echo -eocorre porque não é POSIX e as makechamadas /bin/shque normalmente não são usadas pelo programa usam interativamente e normalmente não foram -eimplementadas. Para portabilidade, use em printf '\t'vez disso.
Jo Então,

No Darwin (macOS), a manpágina do echocomando não menciona a opção -e. No entanto, esta opção é aceita.
ePi272314

75

Use printf, não echo.

Existem várias versões diferentes do echocomando. Existe /bin/echo(que pode ou não ser a versão GNU Coreutils, dependendo do sistema), e o echocomando está embutido na maioria dos shells. Versões diferentes têm maneiras diferentes (ou não) de especificar ou desativar escapes para caracteres de controle.

printf, por outro lado, tem muito menos variação. Ele pode existir como um comando, normalmente /bin/printf, e está embutido em alguns shells (o bash e o zsh têm, o tcsh e o ksh não), mas as várias versões são muito mais parecidas entre si do que as diferentes versões do echo. E você não precisa se lembrar das opções da linha de comando (com algumas exceções; o GNU Coreutils printf aceita --versione --help, e o bash printf embutido aceita -v vararmazenar a saída em uma variável).

Para o seu exemplo:

res='           'x # res = "\t\tx"
printf '%s\n' "[$res]"

E agora é hora de eu admitir que echofuncionará tão bem quanto o exemplo que você está perguntando; você só precisa colocar aspas duplas no argumento:

echo "[$res]"

como escreveu o kmkaplan (há dois anos e meio, eu acabei de notar!). O problema com seus comandos originais:

res='           'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

não está com echo; é que o shell substituiu a aba por um espaço antes echomesmo de ser visto.

echoé bom para saída simples, como echo hello world, mas você deve usá- printflo sempre que quiser fazer algo mais complexo. Você pode começar echoa trabalhar, mas é provável que o código resultante falhe ao executá-lo com uma echoimplementação diferente ou um shell diferente.


1
Eu gostei deste, ele me permite usar o conhecimento de printf e todos os especificadores de formato.
Arun #

@JezenThomas: Não é mais votado porque responde à pergunta de outra maneira que a solicitada. A pergunta menciona especificamente eco, e eco não é um verbo, mas um comando.
Paulo Neves

@PauloNeves: Eu diria que é usado como verbo na pergunta: "Como faço para ecoar um ou mais caracteres de tabulação usando um script bash?"
Keith Thompson

34

Coloque sua string entre aspas duplas :

echo "[$res]"

1
o mesmo aqui - foi o que tentei primeiro. -e funcionou bem embora
froderik

2
Obras @kmkaplan para mim em zsh - não para mim em bash
Kal

34

Você também pode tentar:

echo Hello$'\t'world.

4
+1 para uma solução mais geral. Uso o bash há anos e aprendi isso agora!
Aryeh Leib Taurog

Isso é muito mais geral do que a resposta aceita, pois pode ser usada sem eco.
jwan

22

você precisa usar -e flag para eco, então você pode

echo -e "\t\t x"

16

Na página do manual do bash:

Palavras da forma $ 'string' são tratadas especialmente. A palavra se expande para string, com caracteres de escape com barra invertida substituídos conforme especificado pelo padrão ANSI C.

Então você pode fazer isso:

echo $'hello\tworld'

Por que isso funciona no cli, mas não em um script bash?
Freek

13

Use o verbatim keystroke, ^V( CTRL+V, C-v, qualquer que seja ).

Quando você digita ^Vno terminal (ou na maioria dos editores de Unix), o seguinte caractere é escolhido literalmente . Você pode usar isso para digitar um caractere de tabulação literal dentro de uma string que você está ecoando.

Algo como o seguinte funciona:

echo "^V<tab>"     # CTRL+V, TAB

Documentos bash ( qv , "inserção entre aspas")

inserção entre aspas (Cq, Cv) Adicione o próximo caractere digitado à linha literalmente. Isto é como inserir sequências de teclas como Cq, por exemplo.

nota lateral: de acordo com isso, ALT+TAB deve fazer a mesma coisa, mas todos vinculamos essa sequência à alternância de janelas para que não possamos usá-la

inserção de tabulação (M-TAB) Insere um caractere de tabulação.

-

Nota: você pode usar esta estratégia com todos os tipos de caracteres incomuns. Como um retorno de carro:

echo "^V^M"        # CTRL+V, CTRL+M

Isso ocorre porque o retorno de carro é ASCII 13 e M é a 13ª letra do alfabeto; portanto, quando você digita ^M, obtém o 13º caractere ASCII. Você pode vê-lo em ação usando ls^M, em um prompt vazio, o qual inserirá um retorno de carro, fazendo com que o prompt atue exatamente como você pressiona o retorno. Quando esses caracteres são normalmente interpretados, literalmente você obtém o caractere literal.


1
Gostaria de poder lhe dar mais votos por este. Eu não queria usar -e nos meus argumentos nesse caso, e isso funciona muito bem. Obrigado!
Aaron R.

"... a maioria dos editores de Unix"? Tentei inserir isso com vi e emacs e também não deu os resultados desejados.
GreenMatt

Isso é muuuuito legal! E salvei meu dia ao tentar usar greppara pegar linhas contendo tabcaracteres.
Joël


2

Se você deseja usar echo "a\tb"em um script, execute o script como:

# sh -e myscript.sh

Como alternativa, você pode dar ao myscript.sh a permissão de execução e executar o script.

# chmod +x myscript.sh
# ./myscript.sh

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.