(यहां और क्रमशः) एक 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
perl
regexp ऑपरेटर्स का उपयोग करें :
A="$lhs" B="$rhs" perl -pe 's/\Q$ENV{A}\E/$ENV{B}/g'
perl
(डिफ़ॉल्ट रूप से), लोकेल के कैरेक्टर सेट से प्रभावित नहीं होगा, जैसा कि उपरोक्त में, यह केवल स्ट्रिंग को बाइट्स के सरणियों के रूप में मानता है, जो कि कैरेक्टर (यदि कोई हो) के बारे में परवाह किए बिना वे उपयोगकर्ता के लिए प्रतिनिधित्व कर सकते हैं। साथ sed
, आप करने के लिए स्थान तय करके एक ही प्राप्त कर सकते थे C
के साथ LC_ALL=C
सभी के लिए sed
आदेश (हालांकि वह भी यदि कोई हो, त्रुटि संदेशों में से भाषा को प्रभावित करेगा)।