Caracteres de escape de una variable bash

Caracteres de escape de una variable bash

Estoy intentando buscar y reemplazar cadenas en una plantilla de configuración, usando variables bash.

variables de golpe

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

Plantilla de configuración ( template.conf):

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

Gastos esperados:

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

Esto es fácil para el primer parámetro, usando sed, pero era necesario escapar la barra invertida en el segundo parámetro para 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

Encontré la extensión bash que permitiría agregar comillas simples, es decir ${BACKUP_ROOT@Q}, pero hasta ahora no encontré una opción para escapar de la barra invertida en el BACKUP_ROOTparámetro.

Me pregunto si existe alguna opción elegante para lograrlo. Tenga en cuenta que necesito las variables sin escape en varios otros lugares, por lo que preferiríanopara definirlos adicionalmente con barras invertidas de escape BACKUP_ROOT_ESC="\\/var\\/backup". Eso definitivamente no sería elegante ;)

Yo también preferiríanousar un limitador diferente, porque también tengo otras variables, por ejemplo, contraseñas que pueden contener otros caracteres que coinciden accidentalmente con los delimitadores de búsqueda/reemplazo. Por lo tanto, encontrar una manera de escapar automáticamente de la barra diagonal (y tal vez también de la barra invertida) sería la opción más confiable.

Respuesta1

Por una cuestión de estilo, debes evitar los nombres de variables en mayúsculas.

No es un indicador de expansión como Q, pero puedes usar el genérico ${parameter//pattern/string}con patternuna barra diagonal literal \/y stringuna barra invertida literal: barra diagonal literal \\\/:

$ 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'

información relacionada