एक चर का उपयोग करके शेल स्क्रिप्ट में एक स्ट्रिंग बदलें


93

मैं एक शेल स्क्रिप्ट के अंदर एक स्ट्रिंग को बदलने के लिए नीचे दिए गए कोड का उपयोग कर रहा हूं।

echo $LINE | sed -e 's/12345678/"$replace"/g'

लेकिन यह $replaceउस वैरिएबल के मूल्य के बजाय बदल रहा है ।

क्या कोई बता सकता है कि क्या गलत हुआ?


उन में स्लैश के साथ मूल्यों को संभालने के बारे में सामान्य संबंधित प्रश्न के लिए, stackoverflow.com/questions/5864146/use-slashes-in-rew-replace
tripleee

जवाबों:


146

यदि आप व्याख्या करना चाहते हैं $replace, तो आपको एकल उद्धरण का उपयोग नहीं करना चाहिए क्योंकि वे चर प्रतिस्थापन को रोकते हैं।

प्रयत्न:

echo $LINE | sed -e "s/12345678/\"${replace}\"/g"

यह मानते हुए कि आप उद्धरण चाहते हैं। यदि आप उद्धरण नहीं चाहते हैं, तो उपयोग करें:

echo $LINE | sed -e "s/12345678/${replace}/g"

ट्रांसक्रिप्ट:

pax> export replace=987654321
pax> echo X123456789X | sed "s/123456789/${replace}/"
X987654321X
pax> _

बस यह सुनिश्चित करने के लिए सावधान रहें कि ${replace}इसमें उदाहरण के लिए sed( /उदाहरण के लिए) के रूप में महत्व का कोई वर्ण नहीं है क्योंकि यह भ्रम पैदा करेगा जब तक कि बच न जाए। लेकिन, यदि आप कहते हैं, आप एक संख्या को दूसरे के साथ बदल रहे हैं, तो यह समस्या नहीं होनी चाहिए।


मैं नहीं चाहता कि उद्धरण लगाए गए लोग चाहते हैं कि एक नंबर को दूसरे के साथ बदल दिया जाए
विजय

1
paxdiablo: setयह भी आवश्यक नहीं है (और आप इसे वैसे भी कैसे उपयोग करने जा रहे थे?)। बस replace=987654321
रोमन चेप्लाकाका

मैं आमतौर पर हमेशा exportयह सुनिश्चित करने के लिए उपयोग करता हूं कि चर बच्चों के लिए निर्धारित हैं लेकिन, जैसा कि आप कहते हैं, आप आसानी से इससे बच सकते हैं। हालाँकि, उपयोग या नहीं exportयहाँ अप्रासंगिक है (एक शैली मुद्दा) और इसका वास्तविक उत्तर पर कोई प्रभाव नहीं पड़ता है, जो कि sedकमांड के भीतर चर का उपयोग कैसे किया जाता है ।
paxdiablo

यह समाधान -iविकल्प के साथ काम नहीं करता है। जानोगे क्यों? या इसे कैसे काम करना है?
गेब्रियल

1
हो सकता है कि यह भी कहना है कि एकल से दोहरे उद्धरण चिह्नों का उपयोग करने जा किसी भी आवश्यकता है $या `में sedस्क्रिप्ट डबल-कोटेड तार के लिए खोल के प्रतिस्थापन तंत्र से बचाने के लिए एक बैकस्लैश के साथ भाग जाना है,।
ट्रिपल

73

आप शेल (बैश / क्श) का उपयोग कर सकते हैं।

$ var="12345678abc"
$ replace="test"
$ echo ${var//12345678/$replace}
testabc

3
यह उल्लेख करना चाहते हैं कि बैश-विशिष्ट (और ksh?) है। शायद ज्यादातर लोगों के लिए आयात नहीं, लेकिन हम में से कुछ अभी भी प्राचीन UNIXen :-) पर काम करने के लिए मजबूर हैं
paxdiablo

6
खबरदार, यह डैश पर भी विफल है, जो /bin/shकई आधुनिक लिनक्स पर है।
फ़िहाग

26

प्रश्न के लिए विशिष्ट नहीं है, लेकिन उन लोगों के लिए जिन्हें पिछले उत्तर से स्पष्टता के लिए उसी तरह की कार्यक्षमता की आवश्यकता है:

# create some variables
str="someFileName.foo"
find=".foo"
replace=".bar"
# notice the the str isn't prefixed with $
#    this is just how this feature works :/
result=${str//$find/$replace}
echo $result    
# result is: someFileName.bar

str="someFileName.sally"
find=".foo"
replace=".bar"
result=${str//$find/$replace}
echo $result    
# result is: someFileName.sally because ".foo" was not found

8

एकल उद्धरण बहुत मजबूत हैं। एक बार अंदर जाने के बाद, चर प्रतिस्थापन को लागू करने के लिए आप कुछ भी नहीं कर सकते, जब तक आप छोड़ नहीं देते। इसके बजाय दोहरे उद्धरण चिह्नों का उपयोग करें:

echo $LINE | sed -e "s/12345678/$replace/g"


4
echo $LINE | sed -e 's/12345678/'$replace'/g'

आप अभी भी सिंगल कोट्स का उपयोग कर सकते हैं, लेकिन आपको उन्हें तब "ओपन" करना होगा जब आप चाहते हैं कि चर सही जगह पर विस्तारित हो। अन्यथा स्ट्रिंग को "शाब्दिक रूप से" लिया जाता है (जैसा कि @paxdiablo ने सही कहा है, उसका उत्तर भी सही है)


यह समस्या है कि $replaceकिसी भी उद्धरण के बाहर का उपयोग करने से शेल को व्हॉट्सएप टोकन और वाइल्डकार्ड के विस्तार का प्रदर्शन करना पड़ेगा। यह सरल मूल्यों के साथ काम करता दिखाई देगा, लेकिन नाटकीय रूप से नागों पर नाटकीय रूप से वार कर सकता है। इसे उत्पादन कोड में उपयोग न करें।
ट्रिपल

2

अपने शेल को वेरिएबल का विस्तार करने के लिए, आपको डबल-कोट्स जैसे उपयोग करने की आवश्यकता है

sed -i "s#12345678#$replace#g" file.txt

यह टूट जाएगा यदि $replaceविशेष sedवर्ण ( #, \) हो। लेकिन आप $replaceउन्हें उद्धृत करने के लिए प्रीप्रोसेस कर सकते हैं:

replace_quoted=$(printf '%s' "$replace" | sed 's/[#\]/\\\0/g')
sed -i "s#12345678#$replace_quoted#g" file.txt

0

मुझे इसकी समान आवश्यकता थी लेकिन मेरे प्रतिस्थापित संस्करण में एम्परसैंड था। इस तरह एम्परसैंड से बचकर मेरी समस्या हल हो गई:

replace="salt & pepper"
echo "pass the salt" | sed "s/salt/${replace/&/\&}/g"

-1

इसकी जगह इसका इस्तेमाल करें

echo $LINE | sed -e 's/12345678/$replace/g'

यह मेरे लिए काम करता है बस उद्धरण हटा दें


-2

मैं दोहरे उद्धरण चिह्नों का उपयोग करना पसंद करता हूं, क्योंकि एकल उद्धरण बहुत शक्तिशाली होते हैं क्योंकि हमने उनका उपयोग किया था यदि इसके अंदर कुछ भी बदलने में सक्षम नहीं है या चर सबस्टेशन को लागू कर सकते हैं।

इसलिए दोहरे उद्धरणों का उपयोग करें।

echo $LINE | sed -e "s/12345678/$replace/g"

6
क्या यह डेव के जवाब से अलग है ?
देवनुल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.