Editando o arquivo de configuração através de um script bash

9

Eu tenho tentado escrever um script simples que eu usarei para instalar um aplicativo e atualizar seu arquivo de configuração. Eu estou tendo dificuldade para obter o seu arquivo de configuração modificado.

# DBHost=localhost
DBName=test
# DBPassword=

alguma sugestão de como eu posso ser modificado conforme abaixo?

DBHost=localhost
DBName=database
DBPassword=password
    
por compixtr 03.06.2013 / 20:21

3 respostas

3

A melhor maneira depende se você espera que o arquivo também seja modificado por humanos, quão complexo é o arquivo e se você deseja que seu script tenha precedência se parecer que alguém deseja um valor diferente. Ou seja, se o arquivo já contiver DBPassword=swordfish , você deseja manter isso ou substituí-lo por DBPassword=password ?

Uma forma comum de lidar com isso é ter uma seção do arquivo delimitada por "comentários mágicos" e editar apenas a parte entre esses comentários. Aqui está uma maneira de fazer isso com o awk. Se os comentários mágicos não estiverem presentes, a nova seção será adicionada ao final do arquivo. Aviso: código não testado.

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

Essa abordagem não funciona bem se o programa que lê o arquivo de configuração não suportar várias linhas configurando o mesmo item de configuração. Nesse caso, você realmente precisará remover os antigos. Nesse caso, aconselho deixar os comentários intactos e adicionar suas próprias configurações no final.

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
    
por 03.06.2013 / 20:47
2

Se isso é tudo que você precisa, você poderia fazer algo como

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

Isso copiará o original config.file para config.file.bak e fará as alterações necessárias.

    
por 03.06.2013 / 20:28
2

Eu vou com "ex" no modo silencioso:

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

O comando sed de terdon é compacto e eficiente. Mas a interação de um "documento aqui" cheio de ex-comandos e interpolação de strings de shell pode ser poderosa. Por exemplo, a senha pode ser substituída como o valor de uma variável do shell:

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

Se você usa vi ou vim e está familiarizado com o modo ':', adicionar novas / melhores / diferentes edições também é muito fácil.

    
por 03.06.2013 / 20:43