¿Cómo elimino espacios de las variables de shell?

15

He hecho lo siguiente en la línea de comando:

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

Estoy tratando de usar tr -d ' 'para eliminar los espacios y tener un resultado de:

namewithspace

He intentado algunas cosas como:

text=echo $text | tr -d ' '

¡Hasta ahora no hemos tenido suerte, así que espero que gente maravillosa pueda ayudar!

usuario3347022
fuente

Respuestas:

45

En Bash, puede usar la manipulación de cadenas incorporada de Bash. En este caso, puedes hacer:

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

Para obtener más información sobre los operadores de manipulación de cadenas, consulte http://tldp.org/LDP/abs/html/string-manipulation.html

Sin embargo, su estrategia original también funcionaría, su sintaxis está un poco apagada:

> text2=$(echo $text | tr -d ' ')
> echo $text2
sometextwithspaces
Steven D
fuente
¡Ni siquiera pensé en eso, estaba de humor trabajando en esto! Gran respuesta también!
user3347022
11

No necesita ningún echocomando, solo use Here String en su lugar:

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

Solo por curiosidad, verifiqué cuánto tiempo lleva una tarea tan trivial para diferentes herramientas. Aquí están los resultados ordenados de más lento a más rápido:

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

La operación de shell pura es definitivamente la más rápida, lo que no es sorprendente, ¡pero lo que es realmente impresionante es que es más de 100 veces más rápido que el comando más lento!

jimmij
fuente
Eso no siempre es cierto stackoverflow.com/q/14967299
Steven Penny
5

Simplemente modifique su variable de texto como se muestra a continuación.

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

Sin embargo, si tenemos caracteres de control, esto podría romperse. Entonces, según la sugerencia de Kasperd, podríamos tener comillas dobles a su alrededor. Entonces,

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

Será una mejor versión.

Ramesh
fuente
¡Maravilloso! Estaba muuuy cerca. Como novato, estoy contento de que me dirigía en la dirección correcta. ¡Gracias por la rápida respuesta también, tan pronto como haya esperado 8 minutos, enviaré esto como respuesta!
user3347022
@ user3347022, de nada :)
Ramesh
1
Esto se romperá si $textcontiene caracteres de control, que serían interpretados por el shell. Mejor poner algunas comillas dobles allí:text="$(echo "$text" | tr -d ' ')"
kasperd
@kasperd, gracias por mencionarlo. He incorporado tu sugerencia.
Ramesh
4
$ sed 's. ..g' <<< $text
namewithspace
Steven Penny
fuente
2

un caso especial cuando necesita una variable que tiene un número:

sh:

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

ksh:

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