sed로 대체될 두 개의 PHP 파일이 있습니다.
첫 번째는
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'demo',
'password' => 'demopass',
'database' => 'dbname'
);
쉘 스크립트의 dbname을 동적 변수로 바꿔야 합니다. 이 스크립트를 사용하여 작업했습니다.
sed -i -e "/.*'database' =>*./ s/.*/'database' => '$1',/" /var/www/project/application/config/database.php
두 번째 파일은
$config['timezone'] = 'Asia/Jakarta';
$config['sess_cookie_name'] = 'sess_project';
"Asia/Jakarta"를 다른 동적 변수로 변경해야 하는데 시작 부분에 $ 기호가 있어서 작동하지 않습니다. 이게 내 코드야
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
껍데기확장합니다(아마도 null 값으로). 셸이 확장을 수행하기 때문에 교체된 RHS에서도 이스케이프해야 합니다(정규식 메타 문자로 처리되지 않음).
반면에 [
(즉 ,아니요큰따옴표는 쉘에 특별합니다)예위치에 관계없이 정규식 메타 문자로 처리되므로 이스케이프해야 합니다. ]
(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
인용하다:
답변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에 개행 문자가 없습니다.