(यहां और क्रमशः) एक sकमांड के बाएं हाथ की ओर और दाहिने हाथ की तरफ इस्तेमाल किए जाने वाले चर से बचने के लिए , आप यह करेंगे:sed$lhs$rhs
escaped_lhs=$(printf '%s\n' "$lhs" | sed 's:[][\/.^$*]:\\&:g')
escaped_rhs=$(printf '%s\n' "$rhs" | sed 's:[\/&]:\\&:g;$!s/$/\\/')
sed "s/$escaped_lhs/$escaped_rhs/"
ध्यान दें कि $lhsएक नया वर्ण नहीं हो सकता है।
यही है, एलएचएस पर, सभी regexp ऑपरेटरों ( ][.^$*), भागने वाले चरित्र ( \), और विभाजक ( /) से बचें ।
RHS पर, आपको केवल &विभाजक, बैकस्लैश और न्यूलाइन वर्ण से बचने की आवश्यकता होती है (जो आप पिछले एक ( $!s/$/\\/) को छोड़कर प्रत्येक पंक्ति के अंत में बैकस्लैश सम्मिलित करके करते हैं ।
यही कारण है कि आप का उपयोग हो जाती है /अपने में एक विभाजक के रूप में sed sआदेश और के लिए सक्षम नहीं है कि विस्तारित आर ई के साथ -r(जीएनयू sed/ ssed/ ast/ busybox sed) या -E(BSDs, ast, हाल ही में जीएनयू, हाल ही में बिजीबॉक्स) या PCREs साथ -R( ssed) या संवर्धित आर ई के साथ -A/ -X( ast) जो सभी में अतिरिक्त आरई ऑपरेटर हैं।
मनमाने डेटा के साथ काम करते समय कुछ जमीनी नियम:
- उपयोग न करें
echo
- अपने चर को उद्धृत करें
- लोकेल के प्रभाव पर विचार करें (विशेष रूप से इसका चरित्र सेट: यह महत्वपूर्ण है कि बचने के
sed कमांड उसी लोकेल में चलाए जाते हैं, जो sedकमांड में फरार स्ट्रिंग्स (और उसी sedकमांड के साथ) उदाहरण के लिए उपयोग होता है)
- न्यूलाइन कैरेक्टर के बारे में मत भूलना (यहां आप जांचना चाहते हैं कि क्या
$lhsकोई है और कार्रवाई करें)।
एक अन्य विकल्प यह है कि perlइसके बजाय sedपर्यावरण में स्ट्रिंग्स को पास करें और स्ट्रिंग्स को लेने के लिए \Q/ \E perlregexp ऑपरेटर्स का उपयोग करें :
A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'
perl(डिफ़ॉल्ट रूप से), लोकेल के कैरेक्टर सेट से प्रभावित नहीं होगा, जैसा कि उपरोक्त में, यह केवल स्ट्रिंग को बाइट्स के सरणियों के रूप में मानता है, जो कि कैरेक्टर (यदि कोई हो) के बारे में परवाह किए बिना वे उपयोगकर्ता के लिए प्रतिनिधित्व कर सकते हैं। साथ sed, आप करने के लिए स्थान तय करके एक ही प्राप्त कर सकते थे Cके साथ LC_ALL=Cसभी के लिए sedआदेश (हालांकि वह भी यदि कोई हो, त्रुटि संदेशों में से भाषा को प्रभावित करेगा)।