I have a situation where variables are set in the environment and I have to replace those variable in the file with its value.
Example, I have a lot variable set few of them are FRUIT=APPLE, TIME=DAILY. The content of the text file is
The $$FRUIT$$ is good for health. Everyone should eat $$FRUIT$$ $$TIMES$$.
Now I want a sed command to search any string in $$$$ and use it as env variable to get the value and replace it in the file.
The APPLE is good for health. Everyone should eat APPLE DAILY.
I tried
sed -i -E "s|$$([A-Z]+)$$|${\1}|g" test.txt
and multiple other combination, but its not working.
it gives me error -bash: s|$$([AZ]+)$$|${\1}|g: bad substitution
This steals from my answer to How can I interpret variables on the fly in the shell script? -- this question isn't quite a duplicate of that one.
str='The $$FRUIT$$ is good for health. Everyone should eat $$FRUIT$$ $$TIMES$$'
FRUIT=APPLE
TIMES=DAILY
while [[ $str =~ ('$$'([[:alnum:]_]+)'$$') ]]; do
str=${str//${BASH_REMATCH[1]}/${!BASH_REMATCH[2]}}
done
echo "$str"
The APPLE is good for health. Everyone should eat APPLE DAILY
We search for the template string, capturing the whole string with the dollar signs, and also capture just the variable name within. Then we use shell parameter expansion to replace the matched template string with the value of the variable, using indirect variable expansion .
This steals from the answer to How can I interpret variables on the fly in the shell script? -- this question isn't quite a duplicate of that one.
Provided that the variables are part of the environment:
export FRUIT="APPLE"
export TIMES="DAILY"
You can use the envsubst
GNU tool to perform the variable replacement:
echo 'The $$FRUIT$$ is good for health. Everyone should eat $$FRUIT$$ $$TIMES$$.' | sed -E 's/\$\$([A-Z]+)\$\$/${\1}/g' | envsubst
The APPLE is good for health. Everyone should eat APPLE DAILY.
Note that you need to put a backslash before the $
character since this character has a meaning for sed.
Here's how to do it with only sed
and grep
list=$(grep -wo "\\$\S\S*\\$" test2 | sort -u | tr '$' '\n');
for thing in ${list[@]}; do sed -i 's/\$\$'$thing'\$\$/'$"${!thing}"'/g' test2; done
Below is some explanation (self evident)
user$ echo $TIMES
DAILY
user$ echo $FRUIT
APPLE
user$ cat test2
The $$FRUIT$$ is good for health. Everyone should eat $$FRUIT$$ $$TIMES$$.
user$ list=$(grep -wo "\\$\S\S*\\$" test2 | sort -u | tr '$' '\n');
user$ echo $list
FRUIT TIMES
user$ for thing in ${list[@]}; do sed -i 's/\$\$'$thing'\$\$/'$"${!thing}"'/g' test2; done
user$ cat test2
The APPLE is good for health. Everyone should eat APPLE DAILY.
Here is a way to do this in a single gnu-awk
command using ENVIRON
array, without involving any other utility.
s='The $$FRUIT$$ is good for health. Everyone should eat $$FRUIT$$ $$TIMES$$'
export FRUIT='APPLE'
export TIMES='DAILY'
awk '{
while (match($0, /\$\$([_[:alnum:]]+)\$\$/, a))
$0 = substr($0, 1, RSTART-1) ENVIRON[a[1]] substr($0, RSTART+RLENGTH)
} 1' <<< "$s"
The APPLE is good for health. Everyone should eat APPLE DAILY
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.