Как заменить подстроку из переменной?

Как заменить подстроку из переменной?

Я пытаюсь удалить символы из строковой переменной. У меня это работает 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 (подмножество которых доступно в bashwith shopt -s extglobи zshwith set -o kshglob), чтобы получить эквивалент регулярных выражений (хотя и с другим синтаксисом: *(x)для эквивалента x*здесь):

shopt -s extglob # for bash
# set -o kshglob # for zsh
printf '%s\n' "${MYVAR//[[:alpha:]]*([[:alnum:]-])/}"

Или с zsh extendedglobs, где эквивалентом регулярного выражения *является #:

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-]вместо него ( -должен быть первым или последним, чтобы его можно было воспринимать буквально).

Связанный контент