¿Cómo reemplazar una subcadena de una variable?

¿Cómo reemplazar una subcadena de una variable?

Estoy intentando eliminar caracteres de una variable de cadena. A mi me funciona sedasí:

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

y obtengo:

 --23%§*#

que es lo que estoy buscando. La cadena debe comenzar con una letra y contener sólo letras, dígitos y un guión (-). ¿Hay alguna manera de lograr esto bashreemplazando cadenas?

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

Probé varias combinaciones, pero ninguna funciona como esperaba.

Respuesta1

Necesitaría usar los operadores globales extendidos ksh (un subconjunto de los cuales está disponible en bashwith shopt -s extgloby with zshwith set -o kshglob) para obtener el equivalente de expresiones regulares (aunque con una sintaxis diferente: *(x)para el equivalente de x*aquí):

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

O con zsh extendedglobs donde el equivalente de expresión regular *es #:

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

Algunas notas:

  • ${var/pattern/replacement}reemplaza sólo la primera aparición. Úselo ${var//pattern/replacement}para reemplazar cada aparición (como con la gbandera en sedel scomando).
  • Habías hecho de tu reemplazo un personaje espacial. Utilice ${var//pattern/}(o ${var//pattern}) para reemplazar con la cadena vacía.
  • No desea utilizar echopara generar cadenas arbitrarias
  • Excepto en zsh,las expansiones de variables en contextos de lista deben citarse
  • el comportamiento sería diferente en comparación con su sedenfoque cuando la variable contiene caracteres de nueva línea.
  • [a-z]coincide con caracteres (elementos de clasificación en algunas herramientas) comprendidos entre ay z, cuya lista varía según la configuración regional, el sistema y la herramienta (por ejemplo, [a-z]en bash-4.3una en_GB.UTF-8configuración regional en un sistema GNU coincide con A, X, é, pero no Z). Esto generalmente incluye las 26 letras minúsculas del alfabeto inglés, pero no necesariamente. [[:alpha:]]incluye caracteres (o elementos de cotejo) que se consideranalfabético(independientemente del caso) en su localidad. Si solo desea hacer coincidir las 26 letras en inglés, use [abcdefghijklmnopqrstuvwxyz]o fije la configuración regional en C( LC_ALL=C) y use [a-z]o [[:lower:]]solo para letras minúsculas en inglés o [a-zA-Z]/ [[:alpha:]]para cualquier letra en inglés.
  • [a-z0-9\-]in sedcoincide con el carácter de barra invertida, utilícelo [a-z0-9-]en su lugar ( -debe ser el primero o el último para tomarse literalmente).

información relacionada