bashスクリプトによる設定ファイルの編集


9

私は、アプリケーションのインストールと設定ファイルの更新に使用する単純なbashスクリプトを作成しようとしています。設定ファイルを修正するのに苦労しています。

# DBHost=localhost
DBName=test
# DBPassword=

上記のように以下のように変更する方法はありますか?

DBHost=localhost
DBName=database
DBPassword=password

この非常に一般的なタスクを実行するためだけに、エラーが発生しやすい正規表現を記述する必要があるとは思えません。「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.fileconfig.file.bak、必要な変更を行います。


2

サイレントモードでは「ex」を使用します。

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

terdonのsedコマンドはコンパクトで効率的です。しかし、exコマンドでいっぱいの「ヒアドキュメント」とシェル文字列補間の相互作用は強力です。たとえば、パスワードをシェル変数の値として置き換えることができます。

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

viまたはを使用vimしていて、「:」モードに慣れている場合は、新しい/より良い/異なる編集を追加することも非常に簡単です。


exは強力ですが、エラーから回復することは困難です(たとえば、予期された行が欠落している場合)。ここでは、条件付きの動作なしで回避できますが、これはあまり一般化していません。
Gilles「SO-邪悪なことをやめなさい」
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.