我需要在包含电子邮件地址的文件中将_
(下划线)替换为(问号)。?
该文件如下所示:
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+
不影响其他下划线,仅影响(constant) 和(constant)之间的下划线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'
即替换_
后跟一系列非+
字符,后跟字符@
序列?
,只要匹配就重复该过程。
EMAIL+
或者只在和之间执行此操作SHR
:
sed -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/\1?\2/;t1'
如果您只想考虑以 开头的行^EFT
,您可以添加 a-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
两个下划线都将被替换,因为它们都在 anEMAIL+
和 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