I have the following code at my docker-entrypoint script:
if [[ -v SERVICE_NAMES ]]; then
sudo sed -i -e "s#%SERVICE_NAMES%#$SERVICE_NAMES#g" /etc/someservice/someconfig.file
else
echo "SERVICE_NAMES variable not set, unable to write config without"
exit 1
fi
The content of the variable "SERVICE_NAMES" looks like this on container start:
hostname1,hostname2,hostname3
With my sed command I want to replace the SERVICE_NAMES variable with a placeholder within the someconfig.file, but separated using a whitespace not a comma, so that SERVICE_NAMES looks like this at my someconfig.file:
hostname1 hostname2 hostname3
Is it possible to replace the commas with whitespaces before I write to the file?
tr
to transliterate commas to spacesThe tr
command can be used to transliterate a string (replace a character in a string with another character). The format is as follows:
tr <character> <replacement-character>
tr
gets its input from stdin (file descriptor 0
or /dev/stdin
) so we have to either create a Bash pipeline, use input redirection with process substitution, or use a here-string.
# Pipeline
echo "$SERVICE_NAMES" | tr ',' ' '
# Input Redirection with Process Substitution
tr ',' ' ' <<(echo "$SERVICE_NAMES")
# Here-String
tr ',' ' ' <<<"$SERVICE_NAMES"
In Bash, parameter expansion can be used to replace all of the commas with spaces. The syntax is as follows: ${parameter/pattern/string}
. However, you need to ensure that your pattern begins with another forward slash as per the man pages.
If
pattern
begins with ‘/’, all matches ofpattern
are replaced withstring
. Normally only the first match is replaced.
echo "${SERVICE_NAMES//,/ }"
sed
commandsThe command sed
can execute multiple commands in succession by adding more -e <command>
arguments or by separating the commands with a ;
(semicolon), however, any commands added will be applied to the whole file.
To avoid affecting the whole file, we can make a separate call to sed
with $SERVICE_NAMES
as the data to operate on. We can use sed
's y
command to do transliteration on $SERVICE_NAMES
.
# Pipeline
echo "$SERVICE_NAMES" | sed -e 'y/,/ /'
# Input Redirection with Process Substitution
sed -e 'y/,/ /' <<$(echo "$SERVICE_NAMES")
# Here-String
sed -e 'y/,/ /' <<<"$SERVICE_NAMES"
I won't provide examples for other scripting languages here since there are simply too many. In general, most scripting languages support string splitting, joining strings, regular expressions, string/character substitutions. Some examples of these languages are Python, JavaScript, AWK, and Perl.
For solving issues like this with scripts, you can take your data and either place it directly into the script that will be executed, get the data to standard input (pipelines, input redirection, or here-strings), or utilize command-line arguments.