ドルが機能しないSedシェルスクリプト文字列

ドルが機能しないSedシェルスクリプト文字列

sedに置き換えられる2つの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

2番目のファイルは

$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

引用:

  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 に改行文字がありません。

関連情報