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]
kalyanji
fonte

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                                       | . .|
Johannes Weiss
fonte
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.

Keith Thompson
fonte
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]"
kmkaplan
fonte
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.
jbatista
fonte
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"
Aprendendo
fonte
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'
esoriano
fonte
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.

remer rico
fonte
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
11

Usar eco para imprimir valores de variáveis ​​é uma armadilha comum do Bash. Link de referência:

http://mywiki.wooledge.org/BashPitfalls#echo_.24foo

Anônimo
fonte
Legal, eu gosto do "BashPitfalls", ótimo material e alivio muita dor do meu trabalho diário!
Jerry Tian
+1 porque isso é realmente verdade. Mas observe que a string kalyanji começa com um "[" e não contém nenhum "\".
kmkaplan 28/11
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
ATC
fonte
0
res="\t\tx"
echo -e "[${res}]"
yanghaogn
fonte