Como removo espaços das variáveis ​​do shell?

15

Eu fiz o seguinte na linha de comando:

$ text="name with space"
$ echo $text
name with space

Estou tentando usar tr -d ' 'para remover os espaços e ter um resultado de:

namewithspace

Eu tentei algumas coisas como:

text=echo $text | tr -d ' '

Sem sorte até agora, espero que vocês maravilhosos possam ajudar!

user3347022
fonte

Respostas:

45

No Bash, você pode usar a manipulação de string incorporada do Bash. Nesse caso, você pode fazer:

> text="some text with spaces"
> echo "${text// /}"
sometextwithspaces

Para saber mais sobre os operadores de manipulação de string, consulte http://tldp.org/LDP/abs/html/string-manipulation.html

No entanto, sua estratégia original também funcionaria, sua sintaxe está um pouco diferente:

> text2=$(echo $text | tr -d ' ')
> echo $text2
sometextwithspaces
Steven D
fonte
Eu nem pensei nisso, estava de mau humor trabalhando nisso! Ótima resposta também!
user3347022
11

Você não precisa de nenhum echocomando, basta usar o Here String :

text=$(tr -d ' ' <<< "$text")

Só por curiosidade, verifiquei quanto tempo uma tarefa tão trivial leva para diferentes ferramentas. Aqui estão os resultados classificados da mais lenta para a mais rápida:

abc="some text with spaces"

$ time (for i in {1..1000}; do def=$(echo $abc | tr -d ' '); done)
0.76s user 1.85s system 52% cpu 4.976 total

$ time (for i in {1..1000}; do def=$(awk 'gsub(" ","")' <<< $abc); done)
1.09s user 2.69s system 88% cpu 4.255 total

$ time (for i in {1..1000}; do def=$(awk '$1=$1' OFS="" <<< $abc); done)
1.02s user 1.75s system 69% cpu 3.968 total

$ time (for i in {1..1000}; do def=$(sed 's/ //g' <<< $abc); done)
0.85s user 1.95s system 76% cpu 3.678 total

$ time (for i in {1..1000}; do def=$(tr -d ' ' <<< $abc); done)
0.73s user 2.04s system 85% cpu 3.244 total

$ time (for i in {1..1000}; do def=${abc// /}; done)
0.03s user 0.00s system 59% cpu 0.046 total

A operação pura do shell é definitivamente a mais rápida, o que não é surpreendente, mas o que é realmente impressionante é que é 100 vezes mais rápida que o comando mais lento!

jimmij
fonte
Isso nem sempre é verdade stackoverflow.com/q/14967299 #
911 Steven Penny
5

Apenas modifique sua variável de texto como abaixo.

text=$(echo $text | tr -d ' ')

No entanto, se tivermos caracteres de controle, isso poderá ser interrompido. Assim, conforme a sugestão de Kasperd, poderíamos ter aspas duplas em torno dela. Então,

text="$(echo "$text" | tr -d ' ')"

será uma versão melhor.

Ramesh
fonte
Maravilhoso! Eu estava muuuuito perto. Como noob, estou satisfeito por estar indo na direção certa! Obrigado pela resposta rápida também, assim que eu tiver esperado 8 minutos, enviarei isso como resposta!
user3347022
@ user3347022, você está convidado :)
Ramesh
1
Isso vai quebrar se $textcontiver caracteres de controle, que seriam interpretados pelo shell. Melhor colocar algumas aspas lá:text="$(echo "$text" | tr -d ' ')"
kasperd
@ Kasperd, obrigado por mencionar. Eu incorporei sua sugestão.
Ramesh
4
$ sed 's. ..g' <<< $text
namewithspace
Steven Penny
fonte
2

um caso especial quando você precisa de uma variável que tenha um número:

sh:

typeset -i A=B #or
typeset -i A="   23232"

ksh:

typeset -n A=B #or
typeset -n A="   23232"
Tagar
fonte