Comment supprimer des espaces des variables shell?

15

J'ai fait ce qui suit en ligne de commande:

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

J'essaie d'utiliser tr -d ' 'pour supprimer les espaces et avoir un résultat de:

namewithspace

J'ai essayé quelques choses comme:

text=echo $text | tr -d ' '

Pas de chance jusqu'à présent donc j'espère que vous, les gens merveilleux, pouvez aider!

user3347022
la source

Réponses:

45

Dans Bash, vous pouvez utiliser la manipulation de chaînes intégrée de Bash. Dans ce cas, vous pouvez faire:

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

Pour plus d'informations sur les opérateurs de manipulation de chaînes, voir http://tldp.org/LDP/abs/html/string-manipulation.html

Cependant, votre stratégie d'origine fonctionnerait également, votre syntaxe est juste un peu décalée:

> text2=$(echo $text | tr -d ' ')
> echo $text2
sometextwithspaces
Steven D
la source
Je n'y ai même pas pensé, j'étais d'humeur à travailler là-dessus! Excellente réponse aussi!
user3347022
11

Vous n'avez pas besoin de echocommande du tout, utilisez simplement Here String à la place:

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

Par curiosité, j'ai vérifié combien de temps une tâche aussi triviale prend pour différents outils. Voici les résultats triés du plus lent au plus rapide:

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

Le fonctionnement en shell pur est certainement le plus rapide, ce qui n'est pas surprenant, mais ce qui est vraiment impressionnant, c'est qu'il est plus de 100 fois plus rapide que la commande la plus lente!

jimmij
la source
Ce n'est pas toujours vrai stackoverflow.com/q/14967299
Steven Penny
5

Modifiez simplement votre variable de texte comme ci-dessous.

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

Cependant, si nous avons des personnages de contrôle, cela pourrait casser. Ainsi, selon la suggestion de Kasperd, nous pourrions avoir des guillemets autour. Donc,

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

sera une meilleure version.

Ramesh
la source
Formidable! J'étais tellement proche. En tant que noob, je suis heureux d'avoir pris la bonne direction! Merci également pour la réponse rapide, dès que j'aurai attendu 8 minutes, je soumettrai ceci comme réponse!
user3347022
@ user3347022, vous êtes les bienvenus :)
Ramesh
1
Cela va casser s'il $textcontient des caractères de contrôle, qui seraient interprétés par le shell. Mieux vaut y mettre des guillemets:text="$(echo "$text" | tr -d ' ')"
kasperd
@kasperd, merci de l'avoir mentionné. J'ai intégré votre suggestion.
Ramesh
4
$ sed 's. ..g' <<< $text
namewithspace
Steven Penny
la source
2

un cas particulier lorsque vous avez besoin d'une variable qui a un nombre:

sh:

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

ksh:

typeset -n A=B #or
typeset -n A="   23232"
Tagar
la source