Як видалити пробіли зі змінних оболонок?


15

У командному рядку я зробив наступне:

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

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

namewithspace

Я спробував кілька речей, таких як:

text=echo $text | tr -d ' '

Досі не пощастило, сподіваємось, вам чудовий народ може допомогти!

Відповіді:


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

Я навіть не думав про це, був у настрої tr, працюючи над цим! Чудова відповідь також!
користувач3347022

11

echoКоманда вам взагалі не потрібна , просто використовуйте тут 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 разів швидше, ніж найповільніша команда!


Це не завжди вірно stackoverflow.com/q/14967299
Стівен Пенні,

5

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

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

Однак якщо у нас є контрольні символи, це може зламатися. Отже, згідно з пропозицією Касперда, ми можемо мати подвійні цитати навколо нього. Так,

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

буде кращою версією.


Чудово! Я був так близько. Як noob мені приємно, що я прямував у правильному напрямку! Дякую також за швидку відповідь, як тільки я зачекав 8 хвилин, я надішлю це як відповідь!
user3347022

@ user3347022, ласкаво просимо :)
Рамеш

1
Це порушиться, якщо $textмістить контрольні символи, які будуть інтерпретовані оболонкою. Краще поставте туди дві подвійні лапки:text="$(echo "$text" | tr -d ' ')"
kasperd

@kasperd, дякую, що згадуєте про це. Я включив вашу пропозицію.
Рамеш


2

особливий випадок, коли вам потрібна змінна, яка має число:

ш:

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

ksh:

typeset -n A=B #or
typeset -n A="   23232"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.