Sed to Loop Through File and Replace Placeholder Variables

How to replace ${} placeholders in a text file?

Update

Here is a solution from yottatsa on a similar question that only does replacement for variables like $VAR or ${VAR}, and is a brief one-liner

i=32 word=foo envsubst < template.txt

Of course if i and word are in your environment, then it is just

envsubst < template.txt

On my Mac it looks like it was installed as part of gettext and from MacGPG2

Old Answer

Here is an improvement to the solution from mogsie on a similar question, my solution does not require you to escale double quotes, mogsie's does, but his is a one liner!

eval "cat <<EOF
$(<template.txt)
EOF
" 2> /dev/null

The power on these two solutions is that you only get a few types of shell expansions that don't occur normally $((...)), `...`, and $(...), though backslash is an escape character here, but you don't have to worry that the parsing has a bug, and it does multiple lines just fine.

bash script to replace all occurrences of placeholders in file

I'd use Perl:

perl -pe 's/{{(.*?)}}/$ENV{$1}/g' filename

This assumes that VAR1 and VAR2 are environment variables (i.e., are exported), so that Perl can pick them out of its environment. This would be required of any approach that isn't pure shell; I just mention it to avoid confusion.

This works as follows:

  • s/pattern/replacement/g is a substitution command; you may recognize it from sed. The difference is that here we can use Perl's more powerful regex engine and variables. The g flag makes it so that all matches are replaced; without it, it would apply only to the first.
  • In the pattern, .*? matches non-greedily, so that in a line that contains foo {{VAR1}} bar {{VAR2}} baz, the pattern {{.*?}} matches only {{VAR1}} instead of {{VAR1}} bar {{VAR2}}.
  • The part between {{ and }} is captured because it is between () and can be reused as $1
  • $ENV{$1} in the replacement uses the special %ENV hash that contains the environment of the Perl process. $ENV{$1} is the value of the environment variable that has the name $1, which is the captured group from before.

Replacing placeholders with SED

You can replace your while loop with

. "$property_file"

However, I do not like the eval, and you do not need to declare these settings.

You want sed commands like

sed '/=/ s/\([^=]*\)=\(.*\)/s#\\\[\\\[\1\\\]\\\]#\2#g/' "$property_file"

A lot of backslashes, the [[]] were a difficult choice.

You can use these commands using process substitution:

sed -f <(
sed '/=/ s/\([^=]*\)=\(.*\)/s#\\\[\\\[\1\\\]\\\]#\2#g/' "$property_file"
) "${input_html}"

Replace a single placeholder in a .conf file using bash

There are various alternatives:

To replace them using sed on a "template" and creating a new file, you can do it like this:

sed 's/\$MyPassword/MySuperPassword/' cnlm.conf > cnlm.new.conf

Now, if you will replace into the same file and you don't know the last value of the password, you can do:

sed -ri 's/^(Password *).*$/\1MySuperPassword/' cnlm.conf

If your new password is in a shell variable, then you can execute the last command like this:

newPasswd="abcde" 
sed -ri "s/^(Password *).*$/\1${newPasswd}/" cnlm.conf

Finally, if you want to change the username and the password in the same command:

newUser="user123" 
newPasswd="abcde"
sed -ri "s/^(Username *).*$/\1${newUser}/; s/^(Password *).*$/\1${newPasswd}/" cnlm.conf

How to substitute values in file between 2 strings

Simple sed command based on // string:

sed "s#//[^:/]\+:80/#//$SERVER_IP:80/#" -i $APP_CONFIGMAP_FILE_PATH

Could do the job! (While $SERVER_IP variable don't hold any # character.)

Explanation

Note: Cited paragraph are copied from info sed pages.

  • s is normal replacment command under sed

    The syntax of the 's' command is 's/REGEXP/REPLACEMENT/FLAGS'.
    ...
  • # is used as command separator;

    The '/' characters may be uniformly replaced by any other single
    character within any given 's' command...
  • [^:/] mean any character, but no slashes / and no colons :.

    A "bracket expression" is a list of characters enclosed by '[' and ']'.
    It matches any single character in that list; if the first character of
    the list is the caret '^', then it matches any character *not* in the
    list.
  • * mean any number (even zero) of previous character (no slashes nor colons)

    '*'
    Matches a sequence of zero or more instances of matches for the
    preceding regular expression, which must be an ordinary character,
    a special character preceded by '\', a '.', a grouped regexp (see
    below), or a bracket expression.
    ...
    '\+'
    As '*', but matches one or more.

I insist: Please read carefully info sed!



Related Topics



Leave a reply



Submit