Cách tốt nhất phụ thuộc vào việc bạn mong muốn tệp cũng được sửa đổi bởi con người, mức độ phức tạp của tệp và liệu bạn có muốn tập lệnh của mình được ưu tiên nếu nó trông giống như người khác muốn có giá trị khác. Đó là, nếu tập tin đã chứa DBPassword=swordfish
, bạn có muốn giữ nó, hoặc thay thế nó bằng DBPassword=password
?
Một cách phổ biến để giải quyết vấn đề này là có một phần của tệp được phân định bởi các bình luận ma thuật của Cameron, và chỉ chỉnh sửa phần giữa các bình luận này. Đây là một cách để làm điều này với awk. Nếu không có bình luận ma thuật, phần mới sẽ được thêm vào cuối tập tin. Cảnh báo: mã chưa được kiểm tra.
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
Cách tiếp cận này không hoạt động tốt nếu chương trình đọc tệp cấu hình không hỗ trợ nhiều dòng thiết lập cùng một mục cấu hình. Trong trường hợp đó, bạn sẽ thực sự cần phải loại bỏ những cái cũ. Trong trường hợp này, tôi sẽ khuyên bạn không để lại các bình luận và thêm cài đặt của riêng bạn vào cuối.
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