Лучший способ зависит от того, ожидаете ли вы, что файл также будет изменен людьми, насколько сложен файл, и хотите ли вы, чтобы ваш сценарий имел приоритет, если он выглядит так, как будто кто-то другой хочет другое значение. То есть, если файл уже содержит DBPassword=swordfish
, хотите ли вы сохранить его или заменить на DBPassword=password
?
Обычный способ справиться с этим - иметь раздел файла, разделенный «волшебными комментариями», и редактировать только часть между этими комментариями. Вот способ сделать это с помощью awk. Если волшебные комментарии отсутствуют, новый раздел добавляется в конец файла. Предупреждение: непроверенный код.
begin_marker='# BEGIN AUTOMATICALLY EDITED PART, DO NOT EDIT'
end_marker='# END AUTOMATICALLY EDITED PART'
new_section='DBHost=localhost
DBName=database
DBPassword=password'
export begin_marker end_marker
awk <file.conf >file.conf.new -v begin_marker="$begin_marker" -v begin_marker="$end_marker" -v new_section="$new_section" '
1 {print}
$0 == begin_marker && !changed {
do {getline} while ($0 != end_marker); # discard old section content
print new_section;
print;
changed = 1;
}
END {if (!changed) {print begin_marker; print new_section; print end_marker;}}
'
ln -f file.conf file.conf.old
mv -f file.conf.new file.conf
Этот подход не работает, если программа, которая читает файл конфигурации, не поддерживает несколько строк, устанавливающих один и тот же элемент конфигурации. В этом случае вам действительно нужно удалить старые. В этом случае я бы посоветовал оставить комментарии нетронутыми и добавить свои настройки в конце.
grep -vE '^[[:blank:]]*(DBHost|DBName|DBPassword)=$' <file.conf >file.conf.new
cat <<EOF >>file.conf.new
DBHost=localhost
DBName=database
DBPassword=password
EOF
ln -f file.conf file.conf.old
mv -f file.conf.new file.conf