การแก้ไขไฟล์ปรับแต่งด้วยสคริปต์ทุบตี


9

ฉันพยายามเขียนสคริปต์ทุบตีง่ายๆที่ฉันจะใช้ในการติดตั้งแอปพลิเคชันและอัปเดตเป็นไฟล์ปรับแต่ง ฉันมีเวลายากที่จะได้รับมันเป็นไฟล์ปรับเปลี่ยน

# 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.fileไปconfig.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

sedคำสั่งของ terdon นั้นกะทัดรัดและมีประสิทธิภาพ แต่การโต้ตอบของ "เอกสารที่นี่" ที่เต็มไปด้วยคำสั่ง ex และการแก้ไขสตริงของเชลล์อาจมีประสิทธิภาพ ตัวอย่างเช่นรหัสผ่านอาจถูกแทนที่ด้วยค่าของตัวแปรเชลล์:

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

หากคุณใช้viหรือvimคุณคุ้นเคยกับโหมด ':' การเพิ่มการแก้ไขใหม่ / ดีกว่า / แตกต่างกันก็ค่อนข้างง่าย


ในขณะที่อดีตมีประสิทธิภาพก็ยากที่จะกู้คืนจากข้อผิดพลาด (เช่นเมื่อสายที่คาดว่าจะหายไป) ที่นี่คุณสามารถหนีไปได้โดยไม่มีพฤติกรรมแบบมีเงื่อนไขใด ๆ
Gilles 'หยุดความชั่วร้าย'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.