Bir bash betiği ile yapılandırma dosyasını düzenleme


9

Bir uygulamayı yüklemek ve yapılandırma dosyasını güncellemek için kullanacağım basit bir bash komut dosyası yazmaya çalışıyorum. Bu yapılandırma dosyasını değiştirmek için zor zamanlar yaşıyorum.

# DBHost=localhost
DBName=test
# DBPassword=

herhangi bir öneri nasıl aşağıdaki gibi değiştirilmiş yukarıda alabilirim?

DBHost=localhost
DBName=database
DBPassword=password

Sadece bu çok yaygın görevi yapmak için hataya eğilimli düzenli ifadeler yazmamız gerektiğine inanamıyorum. Gerçekten "update_config test.confg -uncomment_if_pressent DBHost = localhost" gibi standart bir araç olmalıdır.
bigjosh

Yanıtlar:


3

En iyi yol, dosyanın insanlar tarafından da değiştirilmesini bekleyip beklememenize, dosyanın ne kadar karmaşık olduğuna ve birisinin farklı bir değer istemesi durumunda komut dosyanızın öncelik kazanmasını isteyip istemediğinize bağlıdır. Yani, dosya zaten içeriyorsa DBPassword=swordfish, bunu tutmak DBPassword=passwordmı yoksa değiştirmek mi istersiniz?

Bununla başa çıkmanın yaygın bir yolu, dosyanın "sihirli yorumlar" ile ayrılmış bir bölümüne sahip olmak ve yalnızca bu yorumlar arasındaki kısmı düzenlemektir. İşte bunu awk ile yapmanın bir yolu. Sihirli yorumlar yoksa, dosyanın sonuna yeni bölüm eklenir. Uyarı: denenmemiş kod.

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

Yapılandırma dosyasını okuyan program aynı yapılandırma öğesini ayarlayan birden fazla satırı desteklemiyorsa bu yaklaşım işe yaramaz. Bu durumda, eskilerini kaldırmanız gerekir. Bu durumda yorumları el değmeden bırakmanızı ve sonunda kendi ayarlarınızı eklemenizi tavsiye ederim.

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

Bu kodu test ettiniz mi? yoksa hala denenmemiş mi?
rubo77

Buradaki diğer harika örnekler: stackoverflow.com/questions/5955548/…
rubo77

2

Eğer ihtiyacınız olan tek şey buysa,

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

Bu orijinal kopyalar config.fileiçin config.file.bakve gerekli değişiklikleri yapın.


2

Sessiz modda "ex" ile gideceğim:

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

terdon'un sedemri kompakt ve verimlidir. Ancak ex komutları ve kabuk dizesi enterpolasyonu ile dolu bir "burada belge" nin etkileşimi güçlü olabilir. Örneğin, parola bir kabuk değişkeninin değeri olarak değiştirilebilir:

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

' viVeya vim' modunu kullanırsanız ve kullanıyorsanız , yeni / daha iyi / farklı düzenlemeler eklemek de oldukça kolaydır.


Ex güçlü olsa da, hatalardan kurtulmak zordur (örneğin, beklenen bir çizgi eksik olduğunda). Burada herhangi bir koşullu davranış olmadan kaçabilirsiniz, ancak bu çok iyi bir genelleme yapmaz.
Gilles 'SO- kötü olmayı bırak'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.