एक बैश स्क्रिप्ट के माध्यम से कॉन्फ़िगर फ़ाइल को संपादित करना


9

मैं एक सरल बैश स्क्रिप्ट लिखने की कोशिश कर रहा हूं, जिसका उपयोग मैं एक एप्लिकेशन इंस्टॉल करने और इसे कॉन्फ़िगर करने वाली फ़ाइल को अपडेट करने के लिए करूंगा। मैं मुश्किल समय के लिए इसे कॉन्फ़िगर फ़ाइल को संशोधित करने के लिए कर रहा हूँ।

# DBHost=localhost
DBName=test
# DBPassword=

किसी भी सुझाव मैं नीचे के रूप में ऊपर संशोधित कैसे प्राप्त कर सकते हैं?

DBHost=localhost
DBName=database
DBPassword=password

मुझे विश्वास नहीं हो रहा है कि हमें इस सामान्य कार्य को करने के लिए त्रुटि युक्त नियमित अभिव्यक्ति लिखने होंगे। वास्तव में "update_config test.confg -uncomment_if_pressent DBHost = localhost" जैसा एक मानकीकृत उपकरण होना चाहिए।
बिगजोश

जवाबों:


3

सबसे अच्छा तरीका इस बात पर निर्भर करता है कि क्या आप फ़ाइल को मनुष्यों द्वारा संशोधित किए जाने की अपेक्षा करते हैं, फ़ाइल कितनी जटिल है, और क्या आप चाहते हैं कि आपकी स्क्रिप्ट पूर्वता ले ले, अगर ऐसा लगता है कि कोई और अलग मूल्य चाहता है। यही है, यदि फ़ाइल में पहले से ही है DBPassword=swordfish, तो क्या आप उसे रखना चाहते हैं या उसे बदलना DBPassword=passwordचाहते हैं?

इससे निपटने का एक आम तरीका है, "जादू टिप्पणियों" द्वारा सीमांकित फ़ाइल का एक खंड, और केवल इन टिप्पणियों के बीच के हिस्से को संपादित करें। यहाँ जाग के साथ ऐसा करने का एक तरीका है। यदि जादू की टिप्पणियां मौजूद नहीं हैं, तो फ़ाइल के अंत में नया अनुभाग जोड़ा जाता है। चेतावनी: अनकहा कोड।

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

क्या आपने इस कोड का परीक्षण किया? या यह अभी भी अप्रयुक्त है?
रूबो77

अन्य महान उदाहरण यहां: 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 -s $CONFIG_FILE << END_CMDS
%s/^#.DBHost/DBHOST/
%s/DBName=test/DBName=database/
%s/^#.DBPassword/DBPassword/
w!
q
END_CMDS

टेर्डन की sedकमान कॉम्पैक्ट और कुशल है। लेकिन पूर्व कमांड और शेल स्ट्रिंग प्रक्षेप से भरा "यहां दस्तावेज़" की बातचीत शक्तिशाली हो सकती है। उदाहरण के लिए, पासवर्ड को शेल चर के मान के रूप में प्रतिस्थापित किया जा सकता है:

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

यदि आप उपयोग करते हैं viया vimआप ':' मोड से परिचित हैं, तो नए / बेहतर / अलग संपादन जोड़ना भी काफी आसान है।


जबकि पूर्व शक्तिशाली है, त्रुटियों से उबरना मुश्किल है (उदाहरण के लिए जब एक अपेक्षित रेखा गायब है)। यहां आप किसी भी सशर्त व्यवहार के बिना दूर हो सकते हैं, लेकिन यह इतनी अच्छी तरह से सामान्य नहीं करता है।
गिल्स एसओ- बुराई को रोकें '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.