Score:0

Escape characters from a bash variable

cn flag

I am trying to search-and-replace strings in a configuration template, using bash variables.

Bash variables

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

Configuration template (template.conf):

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

Expected outcome:

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

This is easy for the first parameter, using sed, but the backslash in the second parameter needed to be escaped for 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

I found the bash extension that would allow adding single-quotes, i.e. ${BACKUP_ROOT@Q}, but I did not find an option so far to escape the backslash in the BACKUP_ROOT parameter.

I wonder if there is any elegant option to achieve that? Note, that I need the un-escaped variables in several other places, so I would prefer not to additionally define them with escape backslashes BACKUP_ROOT_ESC="\\/var\\/backup". That would definitly not be elegant ;)

I would also prefer not to use a different limiter, because I also have other variables, for example, passwords that may contain other characters accidently matching the search/replace delimiters. So, finding a way to auto-escape the slash (and maybe also the backslash) would be the most reliable option.

Score:4
hr flag

As a matter of style, you should avoid all caps variable names

It's not an expansion flag like Q, but you could use the generic ${parameter//pattern/string} with pattern set to a literal slash \/ and string set to a literal backslash - literal slash \\\/:

$ 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'
BurninLeo avatar
cn flag
Crazy what one can do in the shell :D Thank you very much!
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.