Как удалить пробелы из переменных оболочки?

15

Я сделал следующее в командной строке:

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

Я пытаюсь использовать tr -d ' 'для удаления пробелов и в результате:

namewithspace

Я пробовал несколько вещей, как:

text=echo $text | tr -d ' '

Пока не повезло, надеюсь, вы, замечательный народ, можете помочь!

user3347022
источник

Ответы:

45

В Bash вы можете использовать встроенные в Bash манипуляции со строками. В этом случае вы можете сделать:

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

Подробнее об операторах обработки строк см. Http://tldp.org/LDP/abs/html/string-manipulation.html.

Тем не менее, ваша оригинальная стратегия также сработает, ваш синтаксис немного сбит:

> text2=$(echo $text | tr -d ' ')
> echo $text2
sometextwithspaces
Стивен Д
источник
Я даже не думал об этом, был в хорошем настроении, работая над этим! Отличный ответ!
user3347022
11

Вам вообще не нужна echoкоманда, просто используйте Here String :

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

Просто для любопытства я проверил, сколько времени занимает такая тривиальная задача для разных инструментов. Вот результаты, отсортированные от самого медленного до самого быстрого:

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

Операция с чистой оболочкой определенно самая быстрая, что неудивительно, но что действительно впечатляет, это то, что она работает в 100 раз быстрее самой медленной команды!

jimmij
источник
Это не всегда верно stackoverflow.com/q/14967299
Стивен Пенни
5

Просто измените текстовую переменную, как показано ниже.

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

Однако, если у нас есть управляющие символы, это может сломаться. Итак, согласно предложению Касперда, мы могли бы заключить в него двойные кавычки. Так,

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

будет лучшей версией.

Рамеш
источник
Замечательный! Я был так близко Как нуб я рад, что я направлялся в правильном направлении! Спасибо также за быстрый ответ, как только я подожду 8 минут, я отправлю это как ответ!
user3347022 20.09.14
@ user3347022, пожалуйста :)
Рамеш
1
Это сломается, если $textсодержит управляющие символы, которые интерпретируются оболочкой. Лучше поместите туда двойные кавычки:text="$(echo "$text" | tr -d ' ')"
kasperd
@kasperd, спасибо, что упомянул это. Я включил ваше предложение.
Рамеш
4
$ sed 's. ..g' <<< $text
namewithspace
Стивен Пенни
источник
2

особый случай, когда вам нужна переменная с числом:

ш:

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

КШ:

typeset -n A=B #or
typeset -n A="   23232"
Tagar
источник