видалити конкретні символи зі змінної за допомогою bash


122

Я хочу проаналізувати змінну (в моєму випадку це версія комплекту розробників), щоб зробити її точкою ( .) безкоштовно. Якщо version='2.3.3'бажаний вихід є 233.

Я спробував, як нижче, але це вимагає .замінити іншим символом, який дає мені 2_3_3. Було б добре, якби tr . ''працювали.

  1 VERSION='2.3.3' 
  2 echo "2.3.3" | tr . _

10
Ні, це не вимагає: echo "2.3.3" | tr -d ..
манатство

1
@manatwork Чудово, що працює. Ви можете опублікувати його як відповідь. Спасибі
prayagupd

1
Багато хороших відповідей. Але якщо я можу вдруге відгадати ціль, попередити про 2.11.3 та 2.1.13 ... ;-) Подумайте про додавання нульових знаків до чисел.
Рмано

1
@Rmano Ви маєте на увазі щось подібне VERSION='2.30.3100'? Незалежно від того, що тільки .видалено, усі відповіді тут.
prayagupd

2
@PrayagUpd --- Я просто мав на увазі, що якщо ви будете використовувати число після конвертації для порівняння (якщо сказати, "чи ця версія новіша чи однакова"), ви повинні подбати про випадки, такі як 2.11.3 та 2.1.13 - - вони видаються однаковими після видалення крапки, але явно 2.11.3 новіші. Також 2.11.3 новіше, ніж 2.1.14, але порівняння 2113 та 2114 призведе до неправильної відповіді. Я пам’ятаю помилку десь з цього приводу ...
Рмано

Відповіді:


135

Немає необхідності виконувати зовнішню програму. маніпуляціяbash з рядком може впоратися з нею (також доступна в ksh(звідки вона походить) та zsh):

$ VERSION='2.3.3'
$ echo "${VERSION//.}"
233

(У посібниках з цих оболонок ви можете знайти це в розділі розширення параметрів.)


19
Для подальшої деталізації синтаксис вищевказаної відповіді полягає в тому ${string//substring/replacement}, де, мабуть, відсутність остаточного косого косого перегону та рядка заміни трактується як видалення . Дивіться тут .
sherrellbc

5
Правильно, man bashце говорить явно в Expansion Shell Параметр розділу: « ${parameter/pattern/string}(...) Якщо рядок є марною, тим збіг малюнка віддаляється , і /наступний малюнок . Може бути опущений»
manatwork

1
Моя проблема полягала в тому, що номер версії став таким, "1.0.0"і я хотів просто число, тому слідкуйте за тим, що @manatwork запропонував, що я змінив: "${VERSIONNUM//'"'}"проте я вставляю навіть ' ' тому, що в іншому випадку він не розпізнає ""подібну рядок для зняття.
Alexiscanny

1
@ Алексисканний, ти маєш на увазі, що буквальне значення "присутнє у значенні? Я боюся, це вважається новим питанням, але спробуйте просто уникнути подвійної цитати: "${VERSIONNUM//\"}" pastebin.com/3ECDtkwH
manatwork

1
Чудово !! працює над -ash!
Fr0zenFyr

87

За хронологічним порядком:

тр / сед

echo "$VERSION" | tr -d .
echo "$VERSION" | sed 's/\.//g'

csh / tcsh

echo $VERSION:as/.//

Оболонки POSIX:

set -f
IFS=.
set -- $VERSION
IFS=
echo "$*"

ksh / zsh / bash / yash (і зайнятий ящик ashпри його створенні ASH_BASH_COMPAT)

echo "${VERSION//.}"

зш

echo $VERSION:gs/./

1
tr -d видалив з набору навіть один символ. Для Ex я хочу видалити DCC_ з "DCC_VersionD", він видаляє DCC та D. Очікуваний вихід: VersionD. Фактичний результат: версія. sed працювала як шарм. :) дякую за пост.
кайле

20

Окрім успішних відповідей уже існує. Те саме можна досягти і trз --deleteваріантом.

echo "2.3.3" | tr --delete .

Що виведе: 233


6
на macos --deleteпрапор не розпізнається, але ви можете використовувати його -dзамість цього
Anentropic



4

Perl

$ VERSION='2.3.3'                                     
$ perl -pe 's/\.//g' <<< "$VERSION"           
233

Пітон

$ VERSION='2.3.3'                                     
$ python -c 'import sys;print sys.argv[1].replace(".","")' "$VERSION"
233

Якщо $VERSIONмістять лише цифри та крапки, ми можемо зробити щось ще коротше:

$ python -c 'print "'$VERSION'".replace(".","")'
233

(будьте обережні, це вразливість коду, але якщо вона $VERSIONможе містити будь-який символ).

AWK

$ VERSION='2.3.3'
$ awk 'BEGIN{gsub(/\./,"",ARGV[1]);print ARGV[1]}' "$VERSION"
233

Або це:

$ awk '{gsub(/\./,"")}1' <<< "$VERSION"
233
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.