कैसे sed के साथ स्लैश वाले तारों को बदलने के लिए?


147

मेरे पास एक विजुअल स्टूडियो प्रोजेक्ट है, जिसे स्थानीय स्तर पर विकसित किया गया है। कोड फ़ाइलों को एक दूरस्थ सर्वर पर तैनात किया जाना है। एकमात्र समस्या URLsthey में है जो हार्ड-कोडित हैं।

प्रोजेक्ट में URL = जैसे पृष्ठ = एक है । सर्वर पर मान्य होने वाले लिंक के लिए, यह / पृष्ठ / एक होना चाहिए ।

मैंने तैनाती से पहले sed के साथ अपने कोडफ़ाइल्स में सभी URLS को बदलने का फैसला किया है, लेकिन मैं स्लैश पर अटका हुआ हूं।

मुझे पता है कि यह एक बहुत अच्छा समाधान नहीं है, लेकिन यह बहुत आसान है मुझे बहुत समय बचाएगा। मेरे द्वारा प्रतिस्थापित किए जाने वाले तार की कुल संख्या 10. से कम है। जिन फ़ाइलों को जाँचना है उनकी कुल संख्या ~ 30 है।

मेरी स्थिति का वर्णन करने वाला उदाहरण नीचे दिया गया है:

कमांड मैं उपयोग कर रहा हूं:

sed -f replace.txt < a.txt > b.txt

प्रतिस्थापित करें। जिसमें सभी तार शामिल हैं:

s/?page=one&/pageone/g
s/?page=two&/pagetwo/g
s/?page=three&/pagethree/g

a.txt:

?page=one&
?page=two&
?page=three&

मेरे sed कमांड चलाने के बाद b.txt की सामग्री:

pageone
pagetwo
pagethree

मुझे क्या चाहिए। b.txt में शामिल हैं:

/page/one
/page/two
/page/three


जवाबों:


274

सबसे आसान तरीका यह होगा कि आप अपनी खोज / प्रतिस्थापित लाइनों में एक भिन्न सीमांकक का उपयोग करें, जैसे:

s:?page=one&:pageone:g

आप किसी भी चरित्र को एक सीमांकक के रूप में उपयोग कर सकते हैं जो किसी भी स्ट्रिंग का हिस्सा नहीं है। या, आप इसे बैकस्लैश से बच सकते हैं:

s/\//foo/

कौन सा जगह लेंगे /साथ foo। आप उन मामलों में बच गए बैकस्लैश का उपयोग करना चाहते हैं जहां आपको पता नहीं है कि प्रतिस्थापन स्ट्रिंग्स में क्या अक्षर हो सकते हैं (यदि वे शेल चर हैं, उदाहरण के लिए)।


1
> या, आप इसे बैकस्लैश से बचा सकते हैं। इसका एक उदाहरण अधिक उपयोगी होगा, क्योंकि आप हमेशा यह नहीं जानते कि कुछ अलग करने में सक्षम होने के लिए कौन से अक्षर एक स्ट्रिंग में हैं। जैसे, यह: गूंज / | sed s / \ / a / g काम नहीं करता है: sed: -e अभिव्यक्ति # 1, char 5: अज्ञात विकल्प `s 'के लिए
Max Waterman

1
क्या आप एक जोड़ सकते हैं? धन्यवाद :) मैंने पाया कि दोहरे उद्धरण चिह्नों में काम करने लगता है: इको / | sed "s / \ // a / g"
Max Waterman

@ रेक्सएक्स sedकमांड को दोहरे उद्धरण चिह्नों में प्रयोग करने पर यह मानक संचालन प्रक्रिया है। मैंने अपने उत्तर में उनका उपयोग नहीं किया क्योंकि मैं पूरी sedकमांड लाइन नहीं दिखा रहा था, लेकिन sedओपीजी ने जैसा किया था वैसा ही रीजेक्स कमांड स्ट्रिंग। यदि आप इसे किसी फ़ाइल में रखते हैं, जैसा कि ओपी ने किया है, तो आपको उद्धरण चिह्नों की आवश्यकता नहीं है।
लक्सर

हाँ, पर्याप्त रूप से निष्पक्ष (हालांकि शायद इसका उल्लेख किया जा सकता है)। वह उदाहरण मदद करता है। मुझे लग रहा है कि मुझे कभी-कभी बहुत सारे और बहुत सारे बैकस्लैम लगाने पड़ते हैं ... और यह वास्तव में भ्रमित करने वाला है। जैसे- "s / '/ \\\\\\\ & /" "मुझे लगता है कि पाठ गलत है, हालांकि:" जो foo के साथ \ "की जगह लेगा" - "होना चाहिए जो" बदले / फू के साथ होगा ", नहीं?
मैक्स वॉटरमैन

@MaxWaterman को उस \ _ / पर पकड़ने के लिए धन्यवाद। ठीक कर दिया। यदि आपके पास sedशेल स्क्रिप्ट में एक कमांड है, तो अधिक बैकस्लैश आवश्यक हो सकते हैं (प्रत्येक बैकस्लैश को फिर से बैकस्लैश करने की आवश्यकता होती है)।
लूकर

105

sआदेश परिसीमक के रूप में किसी भी चरित्र का उपयोग कर सकते हैं; sउपयोग के बाद जो भी चरित्र आता है। मैं एक का उपयोग करने के लिए लाया गया था #। इस तरह:

s#?page=one&#/page/one#g

5
OS X पर BSD sed के लिए मैन पेज s कमांड का कहना है : पैटर्न स्पेस में नियमित अभिव्यक्ति के पहले उदाहरण के लिए प्रतिस्थापन स्ट्रिंग को प्रतिस्थापित करें। RE और प्रतिस्थापन को हटाने के लिए स्लैश के बजाय बैकस्लैश या न्यूलाइन के अलावा किसी भी वर्ण का उपयोग किया जा सकता है। मैं पैसे के लिए शर्त लगाता हूं कि GNU sed के लिए मैन पेज कुछ ऐसा ही कहता है।
टॉम एंडरसन

वर्तमान स्वीकृत उत्तर मूल रूप से इस एक के समान है, और एक मिनट पहले पोस्ट किया गया था!
टॉम एंडरसन

61

सेड के बारे में एक बहुत उपयोगी लेकिन कम ज्ञात तथ्य यह है कि परिचित s/foo/bar/कमांड किसी भी विराम चिह्नों का उपयोग कर सकता है, न केवल स्लैश। एक सामान्य विकल्प है s@foo@bar@, जिससे यह स्पष्ट हो जाता है कि आपकी समस्या को कैसे हल किया जाए।


जब आप आगे की स्लैश के लिए स्थानापन्न करना चाहते हैं तो प्रतिभाशाली सलाह। धन्यवाद!
mbb

9

विशेष वर्णों से पहले \ _ जोड़ें:

s/\?page=one&/page\/one\//g

आदि।


4
मुझे कुछ याद आया होगा, लेकिन मैंने यह कोशिश की है और यह काम नहीं कर रहा है। यह कोशिश करने के लिए स्पष्ट लग रहा था, लेकिन मुझे लगता है कि मैं सही हूँ और यह वास्तव में काम नहीं करता है, क्यों इसे पोस्ट करें?
कोडेनोब

4
@codenoob (और कोई भी जो यहां पहुंचता है) - शुरुआत में 'एस' की आवश्यकता होती है। s/foo\/bar/foo_bar/काम करेंगे, लेकिन /foo\/bar/foo_bar/नहीं करेंगे।
MynockSpit

5

एक प्रणाली में मैं विकसित कर रहा हूँ, स्ट्रिंग को sed द्वारा प्रतिस्थापित किया जाना है एक उपयोगकर्ता से इनपुट टेक्स्ट है जिसे एक चर में संग्रहीत किया जाता है और sed को पास किया जाता है।

जैसा कि पहले इस पोस्ट में उल्लेख किया गया है, अगर sed कमांड ब्लॉक के भीतर मौजूद स्ट्रिंग में sed द्वारा उपयोग किया जाने वाला वास्तविक सीमांकक है - तो वाक्यविन्यास त्रुटि पर sed समाप्त हो जाता है। निम्नलिखित उदाहरण पर विचार करें:

यह काम:

$ VALUE=12345
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345

यह टूट जाता है:

$ VALUE=12345/6
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
sed: -e expression #1, char 21: unknown option to `s'

डिफ़ॉल्ट सीमांकक को बदलना मेरे मामले में एक मजबूत समाधान नहीं है क्योंकि मैं उपयोगकर्ता को सीम द्वारा इस्तेमाल किए जाने वाले विशिष्ट वर्णों को परिसीमनकर्ता (जैसे "/") के रूप में सीमित नहीं करना चाहता था।

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

$ VALUE=$(echo ${VALUE} | sed -e "s#/#\\\/#g")
$ echo "MyVar=%DEF_VALUE%" | sed -e s/%DEF_VALUE%/${VALUE}/g
MyVar=12345/6

मैंने इसे विभिन्न लिपियों द्वारा उपयोग किए जाने वाले फ़ंक्शन में बदल दिया है:

escapeForwardSlashes() {

     # Validate parameters
     if [ -z "$1" ]
     then
             echo -e "Error - no parameter specified!"
             return 1
     fi

     # Perform replacement
     echo ${1} | sed -e "s#/#\\\/#g"
     return 0
}

1
मेरे लिए आपके उत्तर से दूर, यह था कि यदि VALUE आप DEF_VALUE को बदलने के लिए उपयोग कर रहे हैं, तो इसमें आगे स्लैश हैं, तो आपको काम करने के लिए sed के लिए उन्हें 3 बैकस्लैश के साथ बचना होगा जैसेVALUE="01\\\/01\\\/2018"
alexkb

3

इस पंक्ति को आपके 3 उदाहरणों के लिए काम करना चाहिए:

sed -r 's#\?(page)=([^&]*)&#/\1/\2#g' a.txt
  • मैं -rकुछ बचकर निकल जाता था।
  • लाइन आपके एक, दो तीन मामले के लिए सामान्य होनी चाहिए। आपको 3 बार उप करने की आवश्यकता नहीं है

अपने उदाहरण के साथ परीक्षण (a.txt):

kent$  echo "?page=one&
?page=two&
?page=three&"|sed -r 's#\?(page)=([^&]*)&#/\1/\2#g'
/page/one
/page/two
/page/three


1

बेनामी से शानदार जवाब। जब मैंने HTML स्ट्रिंग्स में उद्धरणों से बचने की कोशिश की तो मेरी समस्या हल हो गई।

इसलिए यदि आप कुछ HTML टेम्प्लेट (सर्वर पर) वापस करने के लिए sed का उपयोग करते हैं, तो सिंगल के बजाय डबल बैकस्लैश का उपयोग करें:

var htmlTemplate = "<div style=\\"color:green;\\"></div>";

1

sedहै रों tream एड itor , में है कि आप उपयोग कर सकते हैं |भेजने के लिए (पाइप) मानक धाराओं के माध्यम से (STDIN और STDOUT विशेष रूप से) sedऔर उन्हें मक्खी पर प्रोग्राम के रूप में बदल सकता है, यह यूनिक्स दर्शन परंपरा में एक आसान उपकरण बना; लेकिन -iनीचे दिए गए पैरामीटर का उपयोग करके, सीधे भी फ़ाइलों को संपादित कर सकते हैं।
निम्नलिखित पर विचार करें :

sed -i -e 's/few/asd/g' hello.txt

s/करने के लिए प्रयोग किया जाता है रों पाया अभिव्यक्ति ubstitute fewसाथ asd:

कुछ, बहादुर।


अस्स, बहादुर।

/g"वैश्विक" के लिए खड़ा है, जिसका अर्थ है पूरी लाइन के लिए ऐसा करना। यदि आप /g(साथ में s/few/asd/, वहाँ हमेशा तीन स्लैश कोई फर्क नहीं पड़ता) की जरूरत है और fewदो बार एक ही लाइन पर दिखाई देता है, केवल पहले fewको बदल दिया जाता है asd:

कुछ पुरुष, कुछ महिलाएं, बहादुर।


असद पुरुषों, कुछ महिलाओं, बहादुर।

यह कुछ परिस्थितियों में उपयोगी है, जैसे लाइनों की शुरुआत में विशेष वर्णों में फेरबदल करना (उदाहरण के लिए, अधिक से अधिक प्रतीकों की जगह कुछ लोग ईमेल थ्रेड में पिछली सामग्री को क्षैतिज टैब के साथ उद्धृत करने के लिए उपयोग करते हैं, जबकि पंक्ति में बाद में एक असमान असमानता छोड़ते हैं। अछूता), लेकिन आपके उदाहरण में जहां आप निर्दिष्ट करते हैं कि कहीं भी few होता है इसे प्रतिस्थापित किया जाना चाहिए, सुनिश्चित करें कि आपके पास वह है /g

निम्नलिखित दो विकल्प (झंडे) एक में संयुक्त हैं -ie:

-iविकल्प का उपयोग फ़ाइल पर i n स्थान को संपादित करने के लिए किया जाता है hello.txt

-eविकल्प इस मामले में xpression / कमांड को चलाने का संकेत देता है s/

नोट: यह महत्वपूर्ण है कि आप -i -eखोज / प्रतिस्थापन का उपयोग करें। यदि आप करते हैं -ie, तो आप 'ई' अक्षर के साथ हर फाइल का बैकअप बनाते हैं।


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