Escape-Zeichen aus einer Bash-Variable

Escape-Zeichen aus einer Bash-Variable

Ich versuche, mithilfe von Bash-Variablen Zeichenfolgen in einer Konfigurationsvorlage zu suchen und zu ersetzen.

Bash-Variablen

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

Konfigurationsvorlage ( template.conf):

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

Erwartetes Ergebnis:

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

Dies ist für den ersten Parameter mithilfe von einfach sed, der Backslash im zweiten Parameter musste jedoch für maskiert werden 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

Ich habe die Bash-Erweiterung gefunden, die das Hinzufügen von einfachen Anführungszeichen, also , ermöglicht ${BACKUP_ROOT@Q}, habe bisher jedoch keine Option zum Escapen des Backslashs im BACKUP_ROOTParameter gefunden.

Ich frage mich, ob es eine elegante Möglichkeit gibt, dies zu erreichen. Beachten Sie, dass ich die nicht maskierten Variablen an mehreren anderen Stellen benötige, daher würde ich bevorzugennichtdiese zusätzlich mit Escape-Backslashes zu definieren BACKUP_ROOT_ESC="\\/var\\/backup". Das wäre definitiv nicht elegant ;)

Ich würde auch bevorzugennichteinen anderen Begrenzer zu verwenden, da ich auch andere Variablen habe, z. B. Passwörter, die möglicherweise andere Zeichen enthalten, die versehentlich mit den Such-/Ersetzungsbegrenzern übereinstimmen. Daher wäre es die zuverlässigste Option, einen Weg zu finden, den Schrägstrich (und möglicherweise auch den Backslash) automatisch zu maskieren.

Antwort1

Aus Stilgründen sollten Sie Variablennamen in Großbuchstaben vermeiden.

Es handelt sich nicht um ein Erweiterungsflag wie Q, aber Sie können das generische Flag ${parameter//pattern/string}mit pattern„auf einen wörtlichen Schrägstrich setzen“ \/und „ stringauf einen wörtlichen Backslash setzen - wörtlicher Schrägstrich“ verwenden \\\/:

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

verwandte Informationen