
Ich muss in einer Datei mit E-Mail-Adressen _
(Unterstrich) durch ?
(Fragezeichen) ersetzen.
Die Datei sieht wie folgt aus:
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
Die erwartete Ausgabe ist:
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
Wie kann ich dies insedoderawkohne andere Unterstriche zu beeinflussen und nur den Unterstrich zwischen EMAIL+
(constant) und SHR
(constant). Der geänderte Inhalt sollte in einer neuen Datei gespeichert werden.
Antwort1
awk macht Folgendes:
$ 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
Die E-Mail-Adressen befinden sich in Feld 3, daher ersetzen wir nur in Feld 3 _
durch ?
, auch wenn mehr als eine Adresse vorhanden ist _
, mitgsub
.
Antwort2
Mit sed
Ihnen könnten Sie Folgendes tun:
sed -e :1 -e 's/_\([^+]*@\)/?\1/;t1'
Das heißt, ersetzen Sie _
, gefolgt von einer Folge von Nicht- +
Zeichen, gefolgt von @
mit mit ?
der Folge von Zeichen, und wiederholen Sie den Vorgang, bis eine Übereinstimmung vorliegt.
Oder um es nur zwischen EMAIL+
und zu tun SHR
:
sed -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/\1?\2/;t1'
Wenn Sie nur die Zeilen berücksichtigen möchten, die mit beginnen ^EFT
, können Sie ein hinzufügen, -e '/^EFT/!b'
um diejenigen auszuklammern, die nicht mit beginnen:
sed -e '/^EFT/!b' -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/\1?\2/;t1'
Beachten Sie Folgendes für eine Eingabe wie:
EFT EMAIL+ foo_bar SHR bar_baz EMAIL+ SHR
Beide Unterstriche werden ersetzt, da sie beide zwischen „an“ EMAIL+
und „a“ stehen SHR
.
Um dies zu vermeiden, können Sie Folgendes tun:
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 <>%'
Antwort3
sed '/.*EMAIL+\(.*\)SHR.*/{
h;s//\1/;y/_/?/;G
s/\(.*\)\n\(.*EMAIL+\).*SHR/\2\1SHR/}'
Dies sollte ziemlich zuverlässig funktionieren. Es ersetzt alles _
durch ?
zwischen dem letzten EMAIL+
Vorkommen in einer Zeile und dem letzten SHR
Vorkommen in derselben Zeile und nur in den Zeilen, die beide Zeichenfolgen enthalten.