Como substituir uma substring de uma variável?

7

Estou tentando remover caracteres de uma variável de string. Isso funciona para mim com sed assim:

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 a substituição da string bash ?

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

Eu tentei várias combinações, mas nenhuma delas funcionou como eu esperava.

    
por dings 26.10.2016 / 07:31

1 resposta

9

Você precisaria usar os operadores ksh extended glob (um subconjunto deles está disponível em bash com shopt -s extglob e com zsh com set -o kshglob ) para obter o equivalente de expressões regulares (embora com um sintaxe diferente: *(x) para o equivalente de x* aqui):

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

Ou com zsh extendedglob s, onde o equivalente de 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 com o comando g no comando sed ' s ).
  • você fez de seu substituto um personagem espacial. Use ${var//pattern/} (ou ${var//pattern} ) para substituir pela string vazia.
  • Você não deseja usar echo para gerar sequências arbitrárias
  • Exceto em zsh , expansões variáveis em contextos de lista precisam ser citadas
  • o comportamento seria diferente em comparação com sua abordagem sed quando a variável contiver caracteres de nova linha.
  • [a-z] corresponde a caracteres (elementos de agrupamento em algumas ferramentas) compreendidos entre a e z , cuja lista varia de acordo com a localidade, o sistema e a ferramenta (por exemplo [a-z] com bash-4.3 em en_GB.UTF-8 locale 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 considerados alfabéticos (independentemente do caso) em sua localidade. Se você quiser corresponder apenas as 26 letras em inglês, use [abcdefghijklmnopqrstuvwxyz] ou corrija a localidade como C ( LC_ALL=C ) e use [a-z] ou [[:lower:]] somente para letras inglesas minúsculas ou [a-zA-Z] / [[:alpha:]] para qualquer carta em inglês.
  • [a-z0-9\-] in sed corresponde ao caractere de barra invertida, use [a-z0-9-] (o - deve ser o primeiro ou o último a ser obtido literalmente).
por 26.10.2016 / 08:02

Tags