Search and replace variables in a file using bash/sed
Solution 1
This could work:
#!/bin/bash
export user=oracle
export password=oracle123
export dbname=oracle
variable='variable_list'
while read line ;
do
if [[ -n $line ]]
then
exp=$(sed -e 's/\$/\\&/g' <<< "$line")
var=$(sed -e 's/\${\([^}]\+\)}/\1/' <<< "$line")
sed -i "s/$exp/${!var}/g" input.sh
fi
done < "$variable"
The first sed
expression escapes the $ which is a regex metacharacter. The second extracts just the variable name, then we use indirection to get the value in our current shell and use it in the sed
expression.
Edit
Rather than rewriting the file so many times, it's probably more efficient to do it like this, building the arguments list for sed
:
#!/bin/bash
export user=oracle
export password=oracle123
export dbname=oracle
while read var
do
exp=$(sed -e 's/\$/\\&/g' <<< "$var")
var=$(sed -e 's/\${\([^}]\+\)}/\1/' <<< "$var")
args+=("-e s/$exp/${!var}/g")
done < "variable_list"
sed "${args[@]}" input.sh > output.sh
Solution 2
Here is a script.sh that works:
#!/bin/bash
user=oracle
password=oracle123
dbname=oracle
variable='variable_list'
text=$(cat input.sh)
while read line
do
value=$(eval echo $line)
text=$(sed "s/$line/$value/g" <<< "$text")
done < "$variable"
echo "$text" > output.sh
Note that your original version contains single quotes around the sed string, which doesn't insert the value of $line
. It is trying to look for the literal line
after the end of the line $
(which will never find anything).
Since you are looking for the value of the variable in $line
, you need to do an eval to get this.
Also, since there are multiple variables you are looping over, the intermediate text
variable stores the result as it loops.
The export
keyword is also unnecessary in this script, unless it is being used in some sub-process not shown.
Solution 3
user=oracle
password=oracle123
dbname=oracle
variable_list=( '${user}' '${dbname}' )
while IFS="=$IFS" read variable value; do
for subst_var in "${variable_list[@]}"; do
if [[ $subst_var = $value ]]; then
eval "value=$subst_var"
break
fi
done
printf "%s=%s\n" "$variable" "$value"
done < input.sh > output.sh
user1292603
Updated on July 08, 2022Comments
-
user1292603 over 1 year
I am trying to write a bash script(script.sh) to search and replace some variables in input.sh file. But I need to modify only the variables which are present in variable_list file and leave others as it is.
variable_list
${user} ${dbname}
input.sh
username=${user} password=${password} dbname=${dbname}
Expected output file
username=oracle password=${password} > This line won't be changed as this variable(${password}) is not in variable_list file dbname=oracle
Following is the script I am trying to use but I am not able to find the correct sed expression
script.sh
export user=oracle export password=oracle123 export dbname=oracle variable='variable_list' while read line ; do if [[ -n $line ]] then sed -i 's/$line/$line/g' input.sh > output.sh fi done < "$variable"
-
Kaz over 11 years
(mapcar (op list @1 (second [find vars @1 equal first])) entries)
means "map the elements ofentries
through a function which forms a two-element list consisting of the variable, and the result of substituting that variable in thevar
list."[find vars @1 equal first]
means find argument 1 of the anonymous function (the entry) amongvars
usingequal
as the comparison (works with strings), and using thefirst
of each entry as the key (since the entries are two-element lists, the first being the key).find
returns the pair and so(second ...)
gets the value.