bash変数から文字をエスケープする

bash変数から文字をエスケープする

bash 変数を使用して、構成テンプレート内の文字列を検索および置換しようとしています。

Bash変数

BACKUP_KEY="ABCDEFG"
BACKUP_ROOT="/var/backup"

構成テンプレート ( template.conf):

GPG_KEY='BACKUP_KEY_ID'
GPG_OPTS="--pinentry-mode loopback"
TARGET='file://BACKUP_ROOT/partA'
SOURCE='/partA'
MAX_AGE=3M

期待される結果:

GPG_KEY='ABCDEFG'
GPG_OPTS="--pinentry-mode loopback"
TARGET='file:///var/backup/partA'
SOURCE='/partA'
MAX_AGE=3M

これは、最初のパラメータでは を使用して簡単に行えますsedが、 では 2 番目のパラメータのバックスラッシュをエスケープする必要がありましたsed

# What I try
sed "s/BACKUP_KEY/${BACKUP_KEY}/g; s/BACKUP_ROOT/${BACKUP_ROOT}/g" template.conf > ~/.duply/partA/conf
# What this becomes
sed "s/BACKUP_KEY/ABCDEFG/g; s/BACKUP_ROOT//var/backup/g" template.conf > ~/.duply/partA/conf

一重引用符 ( ) を追加できる bash 拡張機能を見つけました${BACKUP_ROOT@Q}が、パラメータ内のバックスラッシュをエスケープするオプションは今のところ見つかりませんでしたBACKUP_ROOT

それを実現するエレガントな方法はあるのだろうか?注意:エスケープされていない変数は他のいくつかの場所でも必要なので、ないさらに、エスケープバックスラッシュを使用して定義しますBACKUP_ROOT_ESC="\\/var\\/backup"。これは明らかにエレガントではありません ;)

私も好むない別のリミッターを使用するのは、たとえばパスワードなど、検索/置換の区切り文字に誤って一致する他の文字が含まれている可能性のある他の変数もあるためです。したがって、スラッシュ (およびおそらくバックスラッシュ) を自動的にエスケープする方法を見つけることが最も信頼性の高いオプションです。

答え1

スタイル上、大文字の変数名は避けるべきです。

これは のような拡張フラグではありませんが、をリテラル スラッシュに設定し、 をリテラル バックスラッシュ - リテラル スラッシュ に設定することで、Q汎用 を使用できます。${parameter//pattern/string}pattern\/string\\\/

$ echo "${BACKUP_ROOT}"
/var/backup

$ echo "${BACKUP_ROOT//\//\\\/}"
\/var\/backup

$ echo "TARGET='file://BACKUP_ROOT/partA'" | sed "s/BACKUP_ROOT/${BACKUP_ROOT//\//\\\/}/"
TARGET='file:///var/backup/partA'

関連情報