我有一个如下所示的列表:
[email protected]
[email protected]
[email protected]
...
我想替换用户名部分中出现的任何点。以便:
[email protected]
变成:
user^[email protected]
我尝试使用 sed 但无法将正则表达式组合在一起以仅将更改应用于用户名部分。您有一个想法可以做到这一点吗?
答案1
使用awk
:
awk -F"@" '{gsub("\.","^",$1)}OFS="@"' file
-F"@"
用 分隔输入@
。gsub()
替换^
第一个字段中的所有点$1
( 之前的名称部分@
)。OFS
设置输出字段分隔符。
答案2
如果有多个点,但 @ 符号后面只有一个点(这很常见),您可以更改所有点并将最后一个点改回:
sed 'y/./^/;s/\(@.*\)\^/\1./'
如果 @ 符号前后可能有多个点,您可以使用一个短循环递归地执行此操作:
sed ':top;s/\.\(.*@\)/^\1/;ttop'
这适用于 GNU sed; BSD sed 需要在标签后有一个换行符:
sed ':top
s/\.\(.*@\)/^\1/;ttop'
编辑:要在单行命令中处理 GNU sed 或 BSD sed 中的所有情况:
sed 'h;s/@.*//;y/./^/;G;s/\n.*@/@/'
h
将当前行(称为“模式空间”)复制到保留空间;该s
命令删除@
及其后面的所有内容;y
与 shell 命令类似tr
,在本例中将所有点转换为插入符号;G
将换行符和保留空间内容附加到模式空间;然后最后一个s
命令删除从换行符到 的内容@
并放回@
.
答案3
如果你只有一个点,你可以使用
sed 's/\.\(.*\)@/^\1@/'
它匹配点,然后捕获其余部分,直到@
,并将其替换为^
、捕获和@
。
答案4
具有 sed 和 awk 的系统通常也会具有 perl,如果您愿意使用 perl 解决方案,请尝试
perl -ne '($user, $domain) = split "@"; $user =~ s/\./^/g; print "$user\@$domain"'
只要您的电子邮件地址相当正常,并且每行包含一个地址(没有其他内容),则可以以简单的方式进行操作:将地址拆分为@
,用脱字符号替换第一部分中的所有句点,然后将两部分一起打印出来作为电子邮件地址。
你也可以变得棘手并这样做:
perl -pe 's/\.(?=.*@)/^/g'
它使用正则表达式用插入符号替换@
符号前面的任何句点。据我所知,它依赖于前瞻断言,该功能在 sed 或 awk 的正则表达式风格中尚未实现。我猜想对于长列表来说这可能会慢一些,但是运行你自己的测试并看看它是否重要。