reemplazar un carácter de una cadena que se encuentra entre la primera y la segunda búsqueda usando sed o awk

reemplazar un carácter de una cadena que se encuentra entre la primera y la segunda búsqueda usando sed o awk

Necesito reemplazar _(guión bajo) con ?(signo de interrogación) en un archivo que contiene direcciones de correo electrónico.

El archivo se parece a continuación:

EFT_020034-E015133  20140624    /ACC/[email protected]         SHR    END 
EFT_020034-E015133  20140624    /ACC/[email protected]     SHR    END
EFT_020034-E015133  20140624    /ACC/[email protected]        SHR    END

El resultado esperado es:

EFT_020034-E015133  20140624    /ACC/[email protected]         SHR    END 
EFT_020034-E015133  20140624    /ACC/[email protected]     SHR    END
EFT_020034-E015133  20140624    /ACC/[email protected]        SHR    END

¿Cómo puedo hacer esto ensedoawksin afectar otros guiones bajos y solo el guión bajo entre EMAIL+(constante) y SHR(constante). El contenido modificado debe guardarse en un archivo nuevo.

Respuesta1

awk hará esto:

$ awk '{ gsub("_", "?", $3) ; print }' < data
EFT_020034-E015133 20140624 /ACC/[email protected] SHR END
EFT_020034-E015133 20140624 /ACC/[email protected] SHR END
EFT_020034-E015133 20140624 /ACC/[email protected] SHR END

Las direcciones de correo electrónico están en el campo 3, por lo que las reemplazamos solo _en ?el campo 3, incluso cuando hay más de una _, usandogsub.

Respuesta2

Con sedusted podría hacer:

sed -e :1 -e 's/_\([^+]*@\)/?\1/;t1'

Es decir, reemplazar _seguido de una secuencia de +caracteres que no son seguidos @de ?la secuencia de caracteres y repetir el proceso siempre que coincida.

O hacerlo solo entre EMAIL+y SHR:

sed -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/\1?\2/;t1'

Si desea considerar solo las líneas que comienzan con ^EFT, puede agregar un -e '/^EFT/!b'para dejar en paz aquellas que no les gustan:

sed -e '/^EFT/!b' -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/\1?\2/;t1'

Tenga en cuenta que para una entrada como:

EFT EMAIL+ foo_bar SHR bar_baz EMAIL+ SHR

Ambos guiones bajos serán reemplazados porque ambos están entre an EMAIL+y a SHR.

Para evitar eso, podrías hacer algo como:

sed '
  /^EFT/!b # leave the non-EFT lines alone (branch out)
  s/%/%p/g; s/</%l/g; s/>/%r/g; # escape the <>% characters with %
  s/EMAIL+/</g; s/SHR/>/g; # replace EMAIL+ and SHR with < and >
  :1
  s/\(<[^<>]*\)_\([^<>]*>\)/\1?\2/; t1
  s/</EMAIL+/g; s/>/SHR/g; # restore EMAIL+ and SHR
  s/%r/>/g; s/%l/</g; s/%p/%/g; # restore the escaped <>%'

Respuesta3

sed '/.*EMAIL+\(.*\)SHR.*/{
    h;s//\1/;y/_/?/;G
    s/\(.*\)\n\(.*EMAIL+\).*SHR/\2\1SHR/}'

Eso debería hacer el trabajo de manera bastante confiable: reemplazará todo _entre ?el último EMAIL+que ocurre en una línea y el último SHRque ocurre en la misma y solo en aquellas líneas que contienen ambas cadenas.

información relacionada