Я пытаюсь удалить символы из строковой переменной. У меня это работает sed
так:
MYVAR=--23ho02123ware38384you443d34o3434ingtod38384day-%§*#sfrf
echo ${MYVAR} | sed -e 's/[a-z][a-z0-9\-]*//g'
и я получаю:
--23%§*#
что я и ищу. Строка должна начинаться с буквы и содержать только буквы, цифры и тире (-). Есть ли способ добиться этого с помощью bash
замены строк?
MYVAR=${MYVAR/[a-z][a-z0-9-]*/ }
Я перепробовал несколько комбинаций, но ни одна из них не сработала так, как я ожидал.
решение1
Вам нужно будет использовать расширенные операторы glob ksh (подмножество которых доступно в bash
with shopt -s extglob
и zsh
with set -o kshglob
), чтобы получить эквивалент регулярных выражений (хотя и с другим синтаксисом: *(x)
для эквивалента x*
здесь):
shopt -s extglob # for bash
# set -o kshglob # for zsh
printf '%s\n' "${MYVAR//[[:alpha:]]*([[:alnum:]-])/}"
Или с zsh
extendedglob
s, где эквивалентом регулярного выражения *
является #
:
set -o extendedglob
printf '%s\n' ${MYVAR//[[:alpha:]][[:alnum:]-]#}
Несколько заметок:
${var/pattern/replacement}
заменяет только первое вхождение. Используйте${var//pattern/replacement}
для замены всех вхождений (как сg
флагом вsed
командеs
).- вы сделали замену пробелом. Используйте
${var//pattern/}
(или${var//pattern}
), чтобы заменить пустой строкой. - Вы не хотите использовать
echo
для вывода произвольных строк - За исключением
zsh
,Расширения переменных в контекстах списков должны быть заключены в кавычки - поведение будет отличаться от вашего
sed
подхода, когда переменная содержит символы новой строки. [a-z]
соответствует символам (элементам сортировки в некоторых инструментах), входящим в диапазон отa
иz
, список которых зависит от локали, системы и инструмента (например,[a-z]
вbash-4.3
локалиen_GB.UTF-8
в системе GNU соответствуетA
,X
,é
,Ẃ
, но неZ
). Обычно это включает 26 строчных букв английского алфавита, но не обязательно.[[:alpha:]]
включает символы (или элементы сортировки), которые считаютсяалфавитный(независимо от регистра) в вашей локали. Если вы хотите сопоставить только 26 английских букв, используйте[abcdefghijklmnopqrstuvwxyz]
или исправьте локаль наC
(LC_ALL=C
) и используйте[a-z]
или[[:lower:]]
только для строчных английских букв или[a-zA-Z]
/[[:alpha:]]
для любой английской буквы.[a-z0-9\-]
соответствуетsed
символу обратной косой черты, используйте[a-z0-9-]
вместо него (-
должен быть первым или последним, чтобы его можно было воспринимать буквально).