假设我有一个包含以下代码行的 PHP 文件:
$to = "example-1_2@example-1_2.com";
我只想更改两个双引号之间的电子邮件地址以表示[email protected]
)。
我已经尝试过这个失败了:
read new_email_address
sed -i 's/^[a-zA-Z0-9-_]*$@^[a-zA-Z0-9-_]*$.^[a-z]*$/"${new_email_address}"/g' FILE
答案1
只是关于您的问题中更新的命令的简短评论sed
,当前内容为
sed -i 's/^[a-zA-Z0-9-_]*$@^[a-zA-Z0-9-_]*$.^[a-z]*$/"${new_email_address}"/g' FILE
请注意,这包含两个无效字符范围(均为 read 0-9-_
),并且该变量new_email_address
不会被 shell 扩展,因为它位于单引号字符串中。我也不确定$@^
and的意图是什么$.^
,因为$
and^
会在表达式中的那些位置上逐字匹配这些字符。
由于没有看到该$to
变量在文件的其余部分中如何使用,我将假设它仅分配到一个位置,并且您显示的行与文件中的行完全一样。
sed 's/$to = ".*";$/$to = "'"$new_email_address"'";/' file >file.new
尝试匹配电子邮件地址是没有意义的,因为我们已经知道该$to
变量包含电子邮件地址。我们唯一需要担心的是试图找到正确的线路。将电子邮件地址与正则表达式匹配是出了名的难的。
这里有几点需要注意:
- in不需要特殊处理,因为它不是出现在表达式的最后
$
。$to
如果您要-E
启用扩展正则表达式,那么首先不要这样做,其次,按照模式中的方式对$
in进行转义。$to
\$
- 该字符串
$to
将不是被视为 shell 变量,因为它位于单引号内。 $new_email_address
是shell 变量,因此我们暂时脱离单引号来引入该变量的值(双引号)。
我建议不要-i
在这里使用,因为您还不知道替换是否正确,或者是否会弄乱文件。最好将结果写入新的文件名。
另外,通过-ir
,您指示sed
使用r
作为备份文件后缀。我假设您想使用该选项-r
(或-E
,这会更普遍支持)。然而,这两者都不-r
需要,-E
因为我们没有使用任何扩展的正则表达式来进行这个简单的替换。
测试上面的命令:
$ cat file
$to = "example-1_2@example-1_2.com";
$ [email protected]
$ sed 's/$to = ".*";$/$to = "'"$new_email_address"'";/' file >file.new
$ cat file.new
$to = "[email protected]";
答案2
如果要替换 (1) 位于两个双引号之间并且 (2) 中间有一个 @ 的字符串,则此正则表达式将与其匹配:
"[a-zA-Z_.-]*@[a-zA-Z_.-]*"
请注意,破折号必须位于每个字符类的末尾,并且我在 @ 之前和之后添加了一个点。
理论上,其他字符也是可能的,例如%。经过一些研究,您可能会发现与电子邮件地址匹配的正则表达式比这更好,但我们假设您的电子邮件地址符合此表达式。
问题出在sed
程序中的替换字符串。您需要将其放在双引号之间,因为它包含 shell 变量,并且正则表达式也包含双引号。
在我看来,处理这个问题的最简单方法是在双引号之前添加反斜杠。例如
sed "s/\"[a-zA-Z0-9_.-]*@[a-zA-Z0-9_.-]*\"/\"${new_email}\"/"