
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 sed
usted 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 SHR
que ocurre en la misma y solo en aquellas líneas que contienen ambas cadenas.