带有美元的 Sed shell 脚本字符串不起作用

带有美元的 Sed shell 脚本字符串不起作用

我有两个 php 文件将被 sed 替换

第一个是

$db['default'] = array(
    'dsn' => '',
    'hostname' => 'localhost',
    'username' => 'demo',
    'password' => 'demopass',
    'database' => 'dbname'
);

我需要将 dbname 从 shell 脚本替换为动态变量 我使用这个脚本并工作

sed -i -e "/.*'database' =>*./ s/.*/'database' => '$1',/" /var/www/project/application/config/database.php

第二个文件是

$config['timezone'] = 'Asia/Jakarta';
$config['sess_cookie_name'] = 'sess_project';

我需要将“亚洲/雅加达”更改为另一个动态变量,但它不起作用,因为它开头有 $ 符号。这是我的代码

sed -i -e "/.*$config['timezone'] = *./ s/.*/$config['timezone'] = '$2';/" /var/www/project/application/config/config.php

谢谢

答案1

这实际上比乍一看更有趣。

至少对于 GNU sed,看起来$只有当它出现在模式末尾时才被视为正则表达式元字符。例如:

$ echo 'config$' | sed 's/config$/foobar$/'
config$

需要是

$ echo 'config$' | sed 's/config\$/foobar$/'
foobar$

$

$ echo '$config' | sed 's/$config/$foobar/'
$foobar

无需逃避即可工作。然而,因为您在 sed 表达式周围使用了弱(双)引号以允许包含文字单引号,所以您需要转义$in$config以防止将其扩展(大概为空值)。因为是 shell 进行扩展,所以它还需要在替换的 RHS 上进行转义(它不会被视为正则表达式元字符)。

另一方面,[(即不是双引号时对 shell 来说是特殊的)无论位置如何,都被视为正则表达式元字符,因此需要转义 - while]当前面没有 (unescaped) 时不需要转义[

最后,如果 的扩展$2可能包含正斜杠(如它所Asia/Jakarta替换的),那么也必须对其进行转义 - 或者您必须将 sed 分隔符更改为其他字符。

所以给出

$ cat config.php
$config['timezone'] = 'Asia/Jakarta';
$config['sess_cookie_name'] = 'sess_project';

var='North America/Chicago'

然后

$ sed -e "/.*\$config\['timezone'] = .*/ s/.*/\$config['timezone'] = '${var//\//\\\/}';/" config.php
$config['timezone'] = 'North America/Chicago';
$config['sess_cookie_name'] = 'sess_project';

(请注意,我还将假定类型更正*..*),或更简单地说

sed -e "/\$config\['timezone']/ s/=.*/= '${var//\//\\\/}';/" config.php

参考:

  1. 在 sh 脚本中使用 sed 时需要转义哪些字符?
  2. sed 查找并替换为斜杠

答案2

你的 sed 似乎过于复杂。我建议(假设这个脚本被称为t):

!/bin/bash
sed -i -e "s~\$config['timezone']\s*=\s*'.*';~\$config['timezone'] = '$1';~i" /var/www/project/application/config/config.php

并像这样调用它:./t 'Asia/Novokuznetsk'。请注意,由于正则表达式分隔符,斜杠不会被转义~。美元符号被转义,除了$1.

答案3

repl_rhs=$(printf '%s\n' "$1" | sed -e 's:[\&/'\'']:\\&:g')
sed -e "
  /\(\$config[[]'timezone'] =\).*/s//\1 '$repl_rhs'/
" file.php
  • 转义 rhs 元字符 + s/// 分隔符 + php 单引号字符串
  • 替换字符串 $1 中没有换行符

相关内容