web-dev-qa-db-ja.com

sedのパス名をbash変換してエスケープする

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

したがって、/var/www\/var\/wwwになります

しかし、私はこれを行う方法がわかりません。

現在、スクリプトはこれでsedを実行します。

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

Bashを使用していると言うので、スラッシュを挿入するためにParameter Expansionを使用できます。

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

これは、

  • 置換directory
  • すべての(//
  • スラッシュ(\/
  • /
  • バックスラッシュ+スラッシュ(\\/)。

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

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

パラメータの拡張/置換を使用します。

${directory////\\/}

説明

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

パラメータ展開 によって提供される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"

ここでの他の答えはすでに素晴らしいですが、/sed以外の別の区切り文字を使用できることを追加したいと思います。 /を含む入力を操作する必要があるときはいつでもこれを行います。

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

あるいは:

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

sedと同じです。 sの後に指定した文字が区切り文字として使用されます。

1
Will