Редактирование конфигурационного файла с помощью bash-скрипта

9

Я пытался написать простой скрипт bash, который я буду использовать для установки приложения и обновления его конфигурационного файла. Я испытываю трудности с тем, чтобы изменить его конфигурационный файл.

# DBHost=localhost
DBName=test
# DBPassword=

Любые предложения, как я могу изменить выше, как показано ниже?

DBHost=localhost
DBName=database
DBPassword=password
compixtr
источник
Я не могу поверить, что мы должны писать подверженные ошибкам регулярные выражения только для того, чтобы выполнить эту очень распространенную задачу. Там действительно должен быть стандартизированный инструмент, такой как «update_config test.confg -uncomment_if_pressent DBHost = localhost».
bigjosh

Ответы:

3

Лучший способ зависит от того, ожидаете ли вы, что файл также будет изменен людьми, насколько сложен файл, и хотите ли вы, чтобы ваш сценарий имел приоритет, если он выглядит так, как будто кто-то другой хочет другое значение. То есть, если файл уже содержит 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
Жиль "ТАК - перестань быть злым"
источник
Вы тестировали этот код? или это еще не проверено?
rubo77
Другие большие примеры здесь: stackoverflow.com/questions/5955548/...
rubo77
2

Если это все, что вам нужно, вы можете сделать что-то вроде

sed  -i.bak -e 's/DBName=.*/DBName=database/' \
 -e 's/#* *DBHost=.*/DBHost=localhost/' \
 -e 's/#* *DBPassword=.*/DBPassword=password/' config.file

Это будет копировать оригинал , config.fileчтобы config.file.bakи внести необходимые изменения.

Тердон
источник
2

Я пойду с «экс» в беззвучном режиме:

ex -s $CONFIG_FILE << END_CMDS
%s/^#.DBHost/DBHOST/
%s/DBName=test/DBName=database/
%s/^#.DBPassword/DBPassword/
w!
q
END_CMDS

Команда Тердона sedкомпактна и эффективна. Но взаимодействие «здесь документа», полного ex-команд и интерполяции строк оболочки, может быть мощным. Например, пароль может быть заменен значением переменной оболочки:

%s/^#.DBPassword=password/DBPassword=$PASSWORD/

Если вы используете viили vimи вы знакомы с режимом «:», добавление новых / улучшенных / различных правок также довольно просто.

Брюс Эдигер
источник
Несмотря на то, что ex является мощным, его трудно восстановить после ошибок (например, когда ожидаемая строка отсутствует). Здесь вы можете уйти без какого-либо условного поведения, но это не очень хорошо обобщает.
Жиль "ТАК - перестань быть злым"