I’m working on a function to perform multiple key=value substitutions with sed:
batch_sub () {
local file="${@: -1}" # Last argument is file to be changed.
[[ -w "${file}" ]] || { echo "Invalid file: ${file}" ; return 1 ; }
for arg in "${@}" ; do
[[ $arg =~ (.*)=(.*) ]] || continue
# 'trim_str' will trim leading & trailing spaces.
local key=$(trim_str "${BASH_REMATCH[1]}")
local value=${BASH_REMATCH[2]}
sed -i 's@'"\(${key}"' *=\).*@\1'"${value}"'@' "${file}"
done
}
this function accepts arguments like:
batch_sub "a = x" "b = y" "c = z" "a.b.d.e=udp://b:8080" "/tmp/file"
and works fine. But what I want is to make it accept arguments like this:
batch_sub "a = x b = y c = z a.b.d.e=udp://b:8080" "/tmp/file"
Furthermore, it would be nice if sed is invoked only once inside this function:
sed -i -e 's/$key=/\1$value/'
-e 's/$key1=/\1$value1/'
'/tmp/file'
please advise.
You can call sed with multiple substitutions at a time.
e.g.
sed -i ‘s/a/b/;s/p/q/’
So from all the arguments, generate a single string, which involves all the substitutions & then call sed once for all.
Why?
“a = x b = y c = z a.b.d.e=udp://b:8080” looks to me as ambiguious.
At least try to have some sort of delimiter for pairs, e.g.
“a = x; b = y; c = z; a.b.d.e=udp://b:8080”