我正在编写一个脚本,其中一部分涉及替换文件中的一些参数。
我正在尝试查找并替换参数并需要调试 sed。
sed -i "s/"$DEFAULT_MAIL_DOMAIN = "padl.com";"/"$DEFAULT_MAIL_DOMAIN = "$E_DOMAIN";"/g" /usr/share/migrationtools/migrate_common.ph
目标文件:
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "padl.com";
# Default base
$DEFAULT_BASE = "dc=padl,dc=com"
脚本:
echo "Enter the email domain"
read E_DOMAIN
echo "The email domain will be "$E_DOMAIN".com"
sleep 2
E_DOMAIN_VAR=$E_DOMAIN.com
sed -i "s/"$DEFAULT_MAIL_DOMAIN = "padl.com";"/"$DEFAULT_MAIL_DOMAIN = "$E_DOMAIN";"/g" /usr/share/migrationtools/migrate_common.ph
答案1
我会推荐类似以下的内容:
sed -i 's|$DEFAULT_MAIL_DOMAIN = \"padl.com\";|$DEFAULT_MAIL_DOMAIN = \"$E_DOMAIN\";|' /usr/share/migrationtools/migrate_common.ph
我所做的改变:
- 更改为 sed 替换周围的单引号。所有这些双引号肯定会引起麻烦。
- sed 替换语法从 更改为
/
。|
这部分不是必需的。我只是更喜欢它。/
如果你愿意的话可以保留。 - 接下来,我删除了搜索和替换文本周围的双引号。不需要他们。
- 转义了文件文本中实际存在的双引号。
- 在 sed 替换结束时删除了全局标志。这看起来像配置文件中的一个参数,每行只会发生一次(可能每个文件也会发生一次)。
答案2
如果$DEFAULT_MAIL_DOMAIN
引号是文件的文字部分,我们需要使用单引号或反斜杠来转义它们。因此,以下任一情况:
$ E_DOMAIN=foobar.com
$ sed -e 's/$DEFAULT_MAIL_DOMAIN = "padl.com"/$DEFAULT_MAIL_DOMAIN = "'"$E_DOMAIN"'"/' file
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foobar.com";
...
$ sed -e "s/\$DEFAULT_MAIL_DOMAIN = \"padl.com\"/\$DEFAULT_MAIL_DOMAIN = \"$E_DOMAIN\"/" file
# Default DNS domain
$DEFAULT_MAIL_DOMAIN = "foobar.com";
首先,引号的解释如下:
'.../$DEFAULT_MAIL_DOMAIN = "'"$E_DOMAIN"'"/'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ - single-quoted, literal ""s
^^^^^^^^^^^ - double-quoted, var expanded
在第二个中,整个内容是一个双引号字符串,其中有问题$
并被"
转义。但不是$
in $E_DOMAIN
,因为我们想扩展该变量。
我不确定变量是否应该是E_DOMAIN
or E_DOMAIN_VAR
,您将.com
后缀添加到后者,但在sed
命令中使用了前者。在任何情况下,变量中的/
、&
或换行符都将由 专门处理sed
,但域名不应包含这些内容。
在您的代码片段中,引用略有偏差:
sed -i "s/"$DEFAULT_MAIL_DOMAIN = "padl.com";"/"$DEFAULT_MAIL_DOMAIN = "$E_DOMAIN";"/g"
第一部分"s/"
是带引号的字符串,然后$DEFAULT_MAIL_DOMAIN
是外部引号,因此扩展为变量(可能扩展为空字符串)。这些空格也没有被引用,因此sed
会得到多个参数,并且可能会抱怨。"padl.com"
再次被引用,但分号没有被引用,因此 shell 会将其解释为结束命令。