A more complex replace into a file?
I run into this type of issue all of the time and haven't found a great way to deal with it.
I want to place gcache.size=3G into a file and it needs to replace or add depending on the situation:
Situation 1: Append to this line
wsrep_provider_options="cert.optimistic_pa=no"
wsrep_provider_options="cert.optimistic_pa=no;gcache.size=3G;"
Situation 2: append but don't put in double ;;
wsrep_provider_options="cert.optimistic_pa=no;"
wsrep_provider_options="cert.optimistic_pa=no;gcache.size=3G;"
Situation 3: If commented out, just add a new line with the value we want set
#wsrep_provider_options="cert.optimistic_pa=no"
wsrep_provider_options="gcache.size=3G"
Situation 4: If doesn't exist, add it
<line doesn't exist>
wsrep_provider_options="gcache.size=3G"
Situation 5: if it's a different value, replace
wsrep_provider_options="cert.optimistic_pa=no;gcache.size=5G;"
wsrep_provider_options="cert.optimistic_pa=no;gcache.size=3G;"
Is there a clever way to do this?
CodePudding user response:
Either you use some dedicated tool for this like Ansible (lineinfile) or you have to code it yourself.
#! /bin/bash
override ()
{
local var_is_set=false
local opt_is_set
local -a options
local option
while read -r line; do
echo "line: $line" >&2
if [[ $line =~ ^(.?)wsrep_provider_options=\"(.*)\" ]]; then
var_is_set=true
if [[ "${BASH_REMATCH[1]}" == '#' ]]; then
printf '%s\n' "$line" 'wsrep_provider_options="gcache.size=3G"'
else
printf 'wsrep_provider_options="'
IFS=';' read -ra options <<< "${BASH_REMATCH[2]}"
opt_is_set=false
for option in "${options[@]}"; do
if [[ $option =~ ^gcache\.size= ]]; then
opt_is_set=true
printf 'gcache.size=3G;'
else
printf 'option ##%s##\n' "$option" >&2
if [[ $option ]]; then
printf '%s;' "$option"
fi
fi
done
if [[ $opt_is_set == false ]]; then
printf "gcache.size=3G;"
fi
printf '"\n'
fi
else
printf '%s\n' "$line"
fi
done
if [[ $var_is_set == false ]]; then
printf '%s\n' 'wsrep_provider_options="gcache.size=3G"'
fi
}
testcase=()
testdata=()
testcase =('Situation 1: Append to this line')
testdata =('wsrep_provider_options="cert.optimistic_pa=no"')
testcase =('Situation 2: append but don'\''t put in double ;;')
testdata =('wsrep_provider_options="cert.optimistic_pa=no;"')
testcase =('Situation 3: If commented out, just add a new line with the value we want set')
testdata =('#wsrep_provider_options="cert.optimistic_pa=no"')
testcase =('Situation 4: If doesn'\''t exist, add it')
testdata =('')
testcase =('Situation 5: if it'\''s a different value, replace')
testdata =('wsrep_provider_options="cert.optimistic_pa=no;gcache.size=5G;"')
for ((i=0 ; i < "${#testcase[@]}" ; i )); do
printf "$(tput bold)%s$(tput sgr0)\n" "${testcase[$i]}"
printf 'Input:\n%s\n' "${testdata[$i]}"
printf 'Output:\n%s\n' "$(override <<< "${testdata[$i]}")"
printf '\n'
done
Notice: SO's syntax highlighting does not work in many cases. They do not feel responsible for the glitches, because the highlighting is done by a third party tool and they are satisfied with the results.