Bash は sed のパス名をエスケープするように変換します。

Bash は sed のパス名をエスケープするように変換します。

私のスクリプトに問題があります。その目的は、呼び出されたファイルの値をパス名に%DIR%なるように変更することです。問題は、ディレクトリ名のスラッシュがsedを台無しにして奇妙なエラーが発生することです。パス名のスラッシュをエスケープスラッシュに変換する必要があります。

だから/var/wwwそれはなります\/var\/www

しかし、どうすればいいのかわかりません。

スクリプトがsedを実行する現在の方法は次のとおりです。

sed -i "s/%DIR%/$directory/g" "$config"

答え1

Bashを使用すると言ったので、次のことができます。パラメータ拡張スラッシュ挿入:

$ directory=/var/www
$ echo "${directory//\//\\/}"
\/var\/www

これは次のように分類されます。

  • 変えるdirectory
  • それぞれ交換(//
  • スラッシュ( \/)
  • そして(/
  • バックスラッシュ+スラッシュ( \\/)。

これをsedコマンドに入れると、次のようになります。

sed -i "s/%DIR%/${directory//\//\\/}/g" "$config"

答え2

/ここにある他の答えはすでに素晴らしいですが、with以外に別の区切り文字を使用できることを追加したかったですsed。以下を含む入力を操作する必要があるたびに/:

sed -i "s@%DIR%@${directory}@g" "$config"

でも:

sed -i "s#%DIR%#${directory}#g" "$config"

すべて同じです。後で区切り文字でsed指定する文字を使用します。s

答え3

パラメータ拡張/代替使用:

${directory////\\/}

説明する

${directory // / / \\/}
            ^  ^ ^  ^
            |  | |  |
            |  | |  replacement, backslash needs to be backslashed
            |  | delimiter
            |  string
        global
      substitution

答え4

bashが提供する文字列操作機能を使用できます。パラメータ拡張、特にフォーム。この文字だけを置き換える必要はありません。文字、、改行、区切り記号の前にはバックスラッシュを付ける必要があります。${VARIABLE//PATTERN/REPLACEMENT}/s\&s

replacement=$directory
replacement=${replacement//\\/\\\\}
replacement=${replacement//\//\\/}
replacement=${replacement//&/\\&}
replacement=${replacement//$'\n'/\\$'\n'}
sed -i "s/%DIR%/$replacement/g" -- "$config"

あるいは、awkやPerlなどの参照を必要としないツールを使用してください。

directory=$directory awk '{gsub(/%DIR%/, ENVIRON["directory"])} 1' <"$config" >"$config.new" &&
mv -- "$config.new" "$config"

または

directory=$directory perl -i -pe 's/%DIR%/$ENV{directory}/g' "$config"

関連情報