我正在尝试为wordpress更新一些设置,我需要使用sed
。当我运行以下命令时,似乎认为该行未完成。我在做什么错了?
$ sed -i 's/define\( \'DB_NAME\', \'database_name_here\' \);/define\( \'DB_NAME\', \'wordpress\' \);/g' /usr/share/nginx/wordpress/wp-settings.php
> ^C
谢谢。
答案 0 :(得分:4)
大多数shell中的单引号不支持任何转义。如果要包含单引号,则需要关闭单引号并添加单引号-可以使用双引号或反斜杠:
sed 's/define\( '\''DB_NAME'\'', '\''database_name_here'\'' \);/define\( '\''DB_NAME'\'', '\''wordpress'\'' \);/g'
我担心它仍然对您不起作用,因为\(
在sed中是特殊的。您可能只需要一个简单的(
。
sed 's/define( '\''DB_NAME'\'', '\''database_name_here'\'' );/define( '\''DB_NAME'\'', '\''wordpress'\'' );/g'
或
sed 's/define( '"'"'DB_NAME'"'"', '"'"'database_name_here'"'"' );/define( '"'"'DB_NAME'"'"', '"'"'wordpress'"'"' );/g'
答案 1 :(得分:1)
通常,在sed
脚本的脚本周围使用单引号是明智的。在这种情况下,双引号会是一个更好的选择-sed
脚本中除了单引号外没有shell元字符:
sed -e "s/define( 'DB_NAME', 'database_name_here' );/define( 'DB_NAME', 'wordpress' );/g" /usr/share/nginx/wordpress/wp-settings.php
或:
sed -e "s/\(define( 'DB_NAME', '\)database_name_here' );/\1wordpress' );/g" /usr/share/nginx/wordpress/wp-settings.php
甚至:
sed -e "/define( 'DB_NAME', 'database_name_here' );/s/database_name_here/wordpress/g" /usr/share/nginx/wordpress/wp-settings.php
要考虑的另一种方法是使用sed
的{{1}}选项将脚本作为文件提供。这使您不必从外壳中转出脚本内容。缺点是您必须创建文件,使用它运行-f
,然后删除该文件。对于当前任务来说,这可能太痛苦了,但它可能是明智的–当您不必担心脱壳时,它无疑可以使生活变得更轻松。
我不认为sed
(全局替换)选项是否适用;您将在包含两个具有默认值的独立g
操作的设置文件中找到几行?
基本代码正常工作后,您可以添加define DB_NAME
选项。请注意,如果您曾经在macOS或基于BSD的系统上工作过,则需要提供后缀作为-i
选项的额外参数(例如,-i
为空后缀或否)备份;或-i ''
,以便能够在Linux(或更准确地说,与GNU -i.bak
)以及macOS和BSD(或更确切地说,与BSD sed
)上都能可靠地工作。吸引POSIX没有帮助;它不支持覆盖选项。
测试用例(第一个示例):
sed
如果$ echo "define( 'DB_NAME', 'database_name_here' );" |
> sed -e "s/\(define( 'DB_NAME', '\)database_name_here' );/\1wordpress' );/g"
define( 'DB_NAME', 'wordpress' );
$
周围的间距不一致,那么您将得到更冗长的正则表达式,使用'DB_NAME'
来代替空格,并且您会发现第三个替代方案比其他,但是第二个可以捕获前导和尾随上下文,并在替换中使用这两个捕获。
分词:这项技术这次有效,因为模式不涉及[[:space:]]*
或$
之类的外壳元字符。通常,脚本确实需要匹配它们,然后在script参数周围使用主要的单引号是明智的。解决另一个任务—用外壳变量 `
的值替换输入中的$DB_NAME
(保持$DB_NAME
不变):
$DB_NAMEORHOST
有三个单独的shell字符串,所有字符串都没有空格。第一个是单引号,包含sed -e 's/$DB_NAME\([^[:alnum:]]\)/'"$DB_NAME"'\1/'
命令的s/…/
部分;第二个是s/…/…/
,shell变量的值用双引号引起来,因此,如果"$DB_NAME"
的值是“自动车辆记录”,则$DB_NAME
仍然有一个参数;第三部分是sed
部分,它放回输入文本中'\1/'
之后的任何字符(观察到,如果$DB_NAME
可能出现在输入行的末尾,则不会匹配)。
大多数正则表达式进行模糊匹配;您必须考虑输入内容的变化,以确定正则表达式必须多努力才能准确地识别材料。