
電子メール アドレスを含むファイル内の_
(アンダースコア) を (疑問符) に置き換える必要があります。?
ファイルは以下のようになります:
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
期待される出力は次のとおりです。
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
どうすればいいですか?sedまたはawkEMAIL+
他のアンダースコアには影響せず、 (定数) と(定数)の間のアンダースコアのみに影響しますSHR
。変更された内容は新しいファイルに保存する必要があります。
答え1
awk はこれを実行します:
$ 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
メールアドレスはフィールド3にあるので、フィールド3のみ_
を で置き換えます?
。複数の がある場合も含みます_
。gsub
。
答え2
次のようなsed
ことができます:
sed -e :1 -e 's/_\([^+]*@\)/?\1/;t1'
つまり、 replace の_
後に非文字のシーケンスが続き、+
その後に文字のシーケンスが続き@
、?
一致する限りこのプロセスを繰り返します。
EMAIL+
または、との間だけ行うには、次のようにしますSHR
。
sed -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/\1?\2/;t1'
で始まる行だけを考慮したい場合は^EFT
、 を追加し-e '/^EFT/!b'
て、気に入らない行をそのままにしておくことができます。
sed -e '/^EFT/!b' -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/\1?\2/;t1'
次のような入力の場合に注意してください:
EFT EMAIL+ foo_bar SHR bar_baz EMAIL+ SHR
EMAIL+
アンダースコアは両方とも anと a の間にあるため、両方とも置き換えられますSHR
。
これを回避するには、次のようにします。
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 <>%'
答え3
sed '/.*EMAIL+\(.*\)SHR.*/{
h;s//\1/;y/_/?/;G
s/\(.*\)\n\(.*EMAIL+\).*SHR/\2\1SHR/}'
これはかなり確実に機能するはずです。つまり、行の最後の文字列と同じ行の最後の文字列の間にある_
すべての文字列を、両方の文字列を含む行でのみ置換します。?
EMAIL+
SHR