En mi bash
script tengo una cadena y su prefijo / sufijo. Necesito eliminar el prefijo / sufijo de la cadena original.
Por ejemplo, supongamos que tengo los siguientes valores:
string="hello-world"
prefix="hell"
suffix="ld"
¿Cómo llego al siguiente resultado?
result="o-wor"
Respuestas:
fuente
${${string#prefix}%suffix}
pero no funciona.Usando sed:
Dentro del comando sed, el
^
carácter coincide con el texto que comienza con$prefix
, y el final$
coincide con el texto que termina con$suffix
.Adrian Frühwirth hace algunos buenos puntos en los comentarios a continuación, pero
sed
para este propósito puede ser muy útil. El hecho de que los contenidos de $ prefix y $ suffix son interpretados por sed puede ser bueno o malo, siempre que prestes atención, deberías estar bien. La belleza es que puedes hacer algo como esto:que puede ser lo que quieras, y es más elegante y más poderoso que la sustitución de variables bash. Si recuerdas que con un gran poder viene una gran responsabilidad (como dice Spiderman), deberías estar bien.
Se 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 funcionaría también:
... pero solo porque:
En general, 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
$prefix
y$suffix
que ciertamente no es lo que queríamos.Observe también mi uso de comillas simples al establecer las variables
prefix
ysuffix
. Ciertamente no queremos que se interprete nada en las cadenas, por lo que las citamos con una sola cita para que no se realice ninguna interpolación. De nuevo, puede que no sea necesario en este ejemplo, pero es un muy buen hábito.fuente
$string
está sujeto a la división de palabras y el bloqueo. 2)$prefix
y$suffix
puede contener expresiones quesed
interpretarán, por ejemplo, expresiones regulares o el carácter utilizado como delimitador que romperá todo el comando. 3) Nosed
es necesario llamar dos veces (puede-e 's///' -e '///'
hacerlo) y también se puede evitar la tubería. Por ejemplo, considerestring='./ *'
y / oprefix='./'
y vea cómo se rompe horriblemente debido a1)
y2)
./
, por lo que usésed "s#^$prefix##
. (Fragilidad: los nombres de archivo no pueden contener#
. Dado que controlo los archivos, estamos a salvo allí).#
como delimitador de sed significaba que no podías manejar archivos que contengan ese carácter.¿Conoces la longitud de tu prefijo y sufijo? En tu caso:
O más general:
¡Pero la solución de Adrian Frühwirth es genial! ¡No sabía sobre eso!
fuente
Uso grep para eliminar prefijos de rutas (que no se manejan bien
sed
):\K
elimina del partido todos los personajes anteriores.fuente
grep -P
Es una extensión no estándar. Más potencia para usted si es compatible con su plataforma, pero este es un consejo dudoso si su código debe ser razonablemente portátil.grep
. Las versiones anteriores en realidad tenían la-P
opción de BSDgrep
pero la eliminaron.Notas:
# $ prefijo: agregar # asegura que la subcadena "infierno" se elimine solo si se encuentra al principio. % $ sufijo: agregar% asegura que la subcadena "ld" se elimine solo si se encuentra al final.
Sin estos, las subcadenas "infierno" y "ld" se eliminarán en todas partes, incluso si se encuentran en el medio.
fuente
/
justo después de la cadena, ¿para qué sirve?Usando el
=~
operador :fuente
Solución pequeña y universal:
fuente
expr
en absoluto. Era una especie de utilidad de fregadero de cocina conveniente en los días de la carcasa original de Bourne, pero ahora ha pasado su fecha de caducidad.Usando la respuesta de @Adrian Frühwirth:
úsalo así
fuente
Haría uso de grupos de captura en regex:
((?:(?!(${suffix})).)*)
se asegura de que el contenido de${suffix}
se excluirá del grupo de captura. En términos de ejemplo, es la cadena equivalente a[^A-Z]*
. De lo contrario, obtendrá:fuente