Como substituir uma substring de uma variável?

Como substituir uma substring de uma variável?

Estou tentando remover caracteres de uma variável de string. Funciona para mim sedassim:

MYVAR=--23ho02123ware38384you443d34o3434ingtod38384day-%§*#sfrf
echo ${MYVAR} | sed -e 's/[a-z][a-z0-9\-]*//g'

e eu recebo:

 --23%§*#

que é o que estou procurando. A string deve começar com uma letra e conter apenas letras, dígitos e um traço (-). Existe uma maneira de conseguir isso com basha substituição de strings?

MYVAR=${MYVAR/[a-z][a-z0-9-]*/ }

Tentei várias combinações, mas nenhuma delas funcionou como esperava.

Responder1

Você precisaria usar os operadores glob estendidos ksh (um subconjunto disponível em bashwith shopt -s extglobe with zshwith set -o kshglob) para obter o equivalente a expressões regulares (embora com uma sintaxe diferente: *(x)para o equivalente x*aqui):

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

Ou com zsh extendedglobs onde o equivalente a regexp *é #:

set -o extendedglob
printf '%s\n' ${MYVAR//[[:alpha:]][[:alnum:]-]#}

Algumas notas:

  • ${var/pattern/replacement}substitui apenas a primeira ocorrência. Use ${var//pattern/replacement}para substituir todas as ocorrências (como o gsinalizador no comando sedde s).
  • você transformou seu substituto em um caractere de espaço. Use ${var//pattern/}(ou ${var//pattern}) para substituir pela string vazia.
  • Você não deseja usar echopara gerar strings arbitrárias
  • Exceto em zsh,expansões de variáveis ​​em contextos de lista devem ser citadas
  • o comportamento seria diferente em comparação com a sua sedabordagem quando a variável contivesse caracteres de nova linha.
  • [a-z]corresponde a caracteres (elementos de agrupamento em algumas ferramentas) compreendidos entre ae z, cuja lista varia de acordo com o código do idioma, o sistema e a ferramenta (por exemplo, [a-z]com bash-4.3em um en_GB.UTF-8código do idioma em um sistema GNU corresponde a A, X, é, , mas não Z). Isso geralmente inclui as 26 letras minúsculas do alfabeto inglês, mas não necessariamente. [[:alpha:]]inclui caracteres (ou elementos de agrupamento) que são consideradosalfabético(independentemente do caso) em sua localidade. Se você deseja corresponder apenas as 26 letras em inglês, use [abcdefghijklmnopqrstuvwxyz]ou corrija a localidade para C( LC_ALL=C) e use [a-z]ou [[:lower:]]apenas para letras minúsculas em inglês ou [a-zA-Z]/ [[:alpha:]]para qualquer letra em inglês.
  • [a-z0-9\-]in sedcorresponde ao caractere de barra invertida, use-o [a-z0-9-]( -deve ser o primeiro ou o último para ser interpretado literalmente).

informação relacionada