Eliminar un prefijo/sufijo fijo de una cadena en Bash

Resuelto Dušan Rychnovský asked hace 11 años • 9 respuestas

Quiero eliminar el prefijo/sufijo de una cadena. Por ejemplo, dado:

string="hello-world"
prefix="hell"
suffix="ld"

¿Cómo obtengo el siguiente resultado?

"o-wor"
Dušan Rychnovský avatar May 18 '13 18:05 Dušan Rychnovský
Aceptado
$ prefix="hell"
$ suffix="ld"
$ string="hello-world"
$ foo=${string#"$prefix"}
$ foo=${foo%"$suffix"}
$ echo "${foo}"
o-wor

Esto está documentado en la sección Expansión de parámetros de Shell del manual:

${parameter#word}
${parameter##word}

La palabra se expande para producir un patrón y se combina de acuerdo con las reglas que se describen a continuación (consulte Coincidencia de patrones ). Si el patrón coincide con el comienzo del valor expandido del parámetro, entonces el resultado de la expansión es el valor expandido del parámetro con el patrón coincidente más corto (el #caso) o el patrón coincidente más largo (el ##caso) eliminado. […]

${parameter%word}
${parameter%%word}

La palabra se expande para producir un patrón y se combina de acuerdo con las reglas que se describen a continuación (consulte Coincidencia de patrones ). Si el patrón coincide con una parte final del valor expandido del parámetro, entonces el resultado de la expansión es el valor del parámetro con el patrón coincidente más corto (el %caso) o el patrón coincidente más largo (el %%caso) eliminado. […]

Adrian Frühwirth avatar May 18 '2013 11:05 Adrian Frühwirth

Usando sed:

$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor

Dentro del comando sed, el ^carácter coincide con el texto que comienza con $prefixy el final $coincide con el texto que termina con $suffix.

Adrian Frühwirth hace algunos buenos puntos en los comentarios a continuación, pero sedpara este propósito puede resultar muy útil. El hecho de que sed interprete el contenido de $prefix y $suffix puede ser bueno O malo; siempre que prestes atención, todo estará bien. Lo bueno es que puedes hacer algo como esto:

$ prefix='^.*ll'
$ suffix='ld$'
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor

que puede ser lo que desea y es más sofisticado y poderoso que la sustitución de variables de bash. Si recuerdas que un gran poder conlleva una gran responsabilidad (como dice Spiderman), deberías estar bien.

Puede encontrar una introducción rápida a sed en http://evc-cit.info/cit052/sed_tutorial.html

Una nota sobre el shell y su uso de cadenas:

Para el ejemplo particular dado, lo siguiente también funcionaría:

$ echo $string | sed -e s/^$prefix// -e s/$suffix$//

...pero sólo porque:

  1. A echo no le importa cuántas cadenas hay en su lista de argumentos, y
  2. No hay espacios en $prefix y $suffix

Generalmente es una buena práctica citar una cadena en la línea de comando porque incluso si contiene espacios, se presentará al comando como un argumento único. Citamos $prefix y $suffix por la misma razón: cada comando de edición para sed se pasará como una cadena. Usamos comillas dobles porque permiten la interpolación variable; si hubiéramos usado comillas simples, el comando sed habría obtenido un literal $prefixy $suffixciertamente no es lo que queríamos.

Observe también mi uso de comillas simples al configurar las variables prefixy suffix. Ciertamente no queremos que se interprete nada en las cadenas, por lo que las comillas simples para que no se produzca interpolación. Nuevamente, puede que no sea necesario en este ejemplo, pero es un muy buen hábito.

 avatar May 17 '2014 19:05