Sed para eliminar entre delimitadores pero mantener el primer delimitador

Sed para eliminar entre delimitadores pero mantener el primer delimitador

Necesito eliminar todo lo que hay entre el segundo =de una cadena y el primero /de una cadena, pero mantenerlo =en su lugar. He probado muchas, muchas cosas, la más reciente de las cuales es

sed -i 's/=[^/]*//

Respuesta1

Basándome únicamente en la descripción del texto, sin entrada/salida de muestra, se me ocurrió esto:

$ echo "foo=bar=baz/quux" | sed 's/\(.*=.*\)=.*\/\(.*\)/\1=\2/'
foo=bar=quux

¿Qué tan cerca se acerca eso a lo que quieres?

Respuesta2

¡Comencé a escribir sobre aserciones de anticipación y retrospectiva solo para descubrir que sed no las admite! Esto debería funcionar:

sed -i 's!\(=[^=]*=\)[^/]*/!\1!'

  • Como usamos /caracteres en la expresión regular, cambiamos el delimitador del scomando a!
  • \(=[^=]*=\)es un grupo de captura que coincide con un =carácter seguido de cero o más caracteres seguidos de otro =carácter. Esta parte es necesaria para asegurarse de que haya dos =caracteres antes de la subcadena que se va a eliminar, como dijo que debía hacerlo.
  • [^/]*/coincide con lo que esté entre los delimitadores y el segundo delimitador
  • \1reemplaza toda la cadena coincidente con lo que coincida con el grupo de captura\(=[^=]*=\)

Respuesta3

Aquí hay una solución conperl

$ echo 'foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
foo=bar=quux

$ echo 'abc=foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
abc=foo=bar=baz/quux

Como se puede ver en los ejemplos anteriores, esto se limita a eliminar texto solo del 2º =al/

  • ^([^=]+=){2}\Kdesde el inicio de la línea busque 2la secuencia de elementos que no sean =texto seguido de =. Significa \Kuna mirada hacia atrás positiva, que no forma parte de la cadena de reemplazo.
  • [^=/]+/significa uno o más no =/caracteres que terminan en/
    • Si se encuentra dicho texto, se elimina

Misma solución consed

$ echo 'foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'
foo=bar=quux

$ echo 'abc=foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'
abc=foo=bar=baz/quux

No admite construcciones de búsqueda anticipada/retrospectiva, por lo que se utiliza el grupo de captura y se hace referencia al mismo al reemplazar

información relacionada