¿Cómo puedo duplicar una línea y buscar y reemplazar el duplicado con sed?

¿Cómo puedo duplicar una línea y buscar y reemplazar el duplicado con sed?

Estoy intentando duplicar líneas en un archivo de texto que contienen ciertos caracteres especiales, pero en el duplicado, sustituyo el carácter especial con caracteres ASCII "normales". El caso de uso concreto son los caracteres acentuados.

Aporte:

éva
test
frédéric

Salida deseada:

éva
eva
test
frédéric
frederic

Por ahora puedo duplicar las líneas que contienen el écarácter, pero no estoy seguro de cómo buscar y reemplazar en el grupo de captura.

Esto es lo que tengo hasta ahora:

echo 'éva\ntest\nfrédéric' | sed 's/\(.*é.*\)/&\n\1/'

¿Puedo hacer eso con sed? Si no, estaré encantado de trabajar con awk...

Respuesta1

Puede hacer coincidir éy luego aplicar múltiples comandos:

sed '/é/{p;s/é/e/g;}'

Para cualquier línea que contenga é, esto imprime el espacio del patrón actual, luego reemplaza todos élos s con e(e imprime el espacio del patrón nuevamente).

El equivalente de AWK es

awk '/é/{print; gsub(/é/, "e")}1'

sedEl scomando puede reutilizar el patrón de dirección:

sed '/é/{p;s//e/g;}'

y si sus reemplazos son todos reemplazos de un solo carácter, el ycomando es más eficiente:

sed '/é/{p;y/é/e/;}'

Respuesta2

$ awk '1; gsub(/é/,"e")' file
éva
eva
test
frédéric
frederic

Los usos anteriores:

  1. La condición idiomática verdadera 1para hacer que awk realice la acción predeterminada de imprimir la línea actual, luego:
  2. gsub()para reemplazar cualquier és con es y si eso encontró/reemplazó algún és, entonces su retorno positivo usado en el contexto de condición nuevamente hace que awk realice la acción predeterminada de imprimir la línea actual (ahora modificada).

Tenga en cuenta que al utilizar el código de retorno de gsub()para indicarnos si ése encontró algún mensaje de correo electrónico, nos evita tener que especificar de forma redundante la misma expresión regular /é/dos veces en el comando.

Respuesta3

Otra sedopción más, inspirada enawkLa respuesta de @EdMorton

sed -n 'p;s/é/e/gp' file

Respuesta4

Otra opción,similar al de @Stephen Kitt:

$ sed '/é/p;s/é/e/g'
éva
eva
test
frédéric
frederic

  • /é/pseleccione las líneas que tienen un écarácter e imprima.
  • s/é/e/gimprime las líneas anteriores con la sustitución.

información relacionada