单引号内的 sed 命令字符串变量连接

sed command string variable concatenation within single quotes

我想使用 sed 修改 php.ini 文件中的 include_path 指令。下面,我有一个命令查找一个字符串并将指令放在匹配后的一行上。但是,在 ${install_path} 变量中仍然保持双引号的同时,我无法让它工作。双引号必须在那里。

我要编辑的文件是php.ini。这是我的目标前后的几行,也就是 "UNIX: ":

之后的那一行
;;;;;;;;;;;;;;;;;;;;;;;;;
; Paths and Directories ;
;;;;;;;;;;;;;;;;;;;;;;;;;

; UNIX: "/path1:/path2"
;include_path = "/path1:/path2"
;
; Windows: "\path1;\path2"

install_path 定义为:

install_path="/var/www/mainapp"

我在下面使用的 sed 命令搜索字符串匹配项,然后在其正下方创建一个新行:

sed -i '/; UNIX: "\/path1:\/path2"/a include_path = "${install_path}/lib"' /etc/php.ini

php.ini 内的预期输出是:

; UNIX: "/path1:/path2"
include_path = "/var/www/mainapp/lib"

include_path 行是在“; UNIX:...”行之后创建的

感谢您的帮助。

sed 用于在单行上进行简单替换,仅此而已。对于任何更有趣的事情,您应该使用 awk。您可能想要这样的东西:

awk -v install_path="$install_path" '
{ print }
/; UNIX: "\/path1:\/path2"/ { printf "include_path = \"%s/lib\"\n", install_path }
' /etc/php.ini

但没有示例输入和预期输出,这只是猜测。要替换原始文件的内容,只需在末尾添加 > tmp && mv tmp /etc/php.ini 或在 GNU awk 前面使用 -i inplace

您的主要问题是绕过 shell 的引用约定,同时保留文件中的引号。

你说你已经定义了install_path="/var/www/mainapp";请注意,引号已被 shell 删除,因此该字符串不包含引号。这在下面很重要。新旧对比:

旧:

sed -i '/; UNIX: "\/path1:\/path2"/a include_path = "${install_path}/lib"' /etc/php.ini

新:

sed -i '/; UNIX: "\/path1:\/path2"/a include_path = "'"${install_path}/lib"'"' /etc/php.ini

呃什么?您已正确地将脚本括在单引号中,但这会阻止 shell 扩展 ${install_path}。因此,您必须终止单引号字符串,但您希望在输出中使用双引号,所以我将单引号放在双引号之后。然后我也将 ${install_path} 中的值用双引号引起来:"${install_path}/lib"。双引号对于您引用的值并不重要,但通常使用它们是个好主意。然后我恢复单引号,第一个字符是 .ini 文件中包含路径字符串的右双引号,然后关闭单引号字符串。是的,还有其他方法可以写出最后一点,但要说服我使用反斜杠的替代方法更好。

如果您确实保留了安装路径值周围的双引号:

install_path='"/var/www/mainapp"'

你可以使用:

sed -i '/; UNIX: "\/path1:\/path2"/a include_path = '"${install_path}/lib" /etc/php.ini

另请注意,只有 GNU sed 允许您将 'appended text' 与 a 命令放在同一行。 POSIX sed 不会,其他平台上 sed 的其他变体也不会。例如,在 Mac OS X 上,你必须写:

sed -i '/; UNIX: "\/path1:\/path2"/a\
include_path = '"${install_path}/lib" /etc/php.ini