2012-05-31 4 views
40

मैं एक शेल स्क्रिप्ट में sed कमांड का उपयोग करने की कोशिश कर रहा हूं, जहां मैं STARTremoveThisComment और removeThisCommentEND पढ़ने वाली रेखाओं को पढ़ने वाली रेखाओं को हटाना चाहता हूं।मैं उसी फ़ाइल के रूप में इनपुट और आउटपुट के साथ sed कमांड कैसे चला सकता हूं?

मैं यह करने के लिए जब मैं इसे

sed 's/STARTremoveThisComment//' > test 

का उपयोग कर एक नई फ़ाइल में कॉपी कर सकती हूं लेकिन मैं कैसे इनपुट और आउटपुट के रूप में एक ही फाइल का उपयोग करके ऐसा करते हैं?

+1

एसईडी -es/some1/some2/जी input.file> output.file; – 0xAX

उत्तर

72

sed -i (या विस्तारित संस्करण, --in-place) को स्वचालित प्रक्रिया सामान्य रूप से, कम उन्नत कार्यान्वयन के साथ किया, अस्थायी फ़ाइल को आउटपुट भेजने तो वह वापस मूल करने के लिए नाम बदलने की है कि होगा।

-i यथा-स्थान संपादन के लिए है, और आप भी मूल की एक प्रति रखने के लिए एक बैकअप प्रत्यय प्रदान कर सकते हैं:

sed -i.bak fileToChange 
sed --in-place=.bak fileToChange 

उन दोनों fileToChange.bak में मूल फ़ाइल रखेंगे।

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

आप एक अधिक आदिम कार्यान्वयन का उपयोग कर रहे हैं, तो आप की तरह कुछ का उपयोग कर सकते हैं:

sed 'whatever' oldfile >newfile ; mv newfile oldfile 

हालांकि कुछ और त्रुटि जाँच अच्छा होगा।

+1

एक आकर्षण की तरह काम किया! :) इस मैं क्या प्रयोग किया जाता है: 'sed मैं के/STARTremoveThisComment // 'test' –

+1

ध्यान दें कि' --in-place' एक gnuism है और सभी संस्करणों में काम नहीं करेगा sed की। यदि आप गैर-लिनक्स मशीनों पर अपनी sed स्क्रिप्ट का उपयोग करने की अपेक्षा करते हैं, तो आप इसका उपयोग नहीं कर सकते हैं। –

+0

@william, मैं उस के बारे में सोच लेकिन बहुत उत्तेजित के बाद से सवाल एक लिनक्स टैग नहीं था था। मैं स्पष्ट करूंगा। मैक के लिए – paxdiablo

0

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

sed -e s/try/this/g input.file > output.file;mv output.file input.file 
+2

input.file mv output.file कम से कम इस 'sed नहीं किया जाना चाहिए। .. और एमवी ... 'तो एक sed विफलता एक खाली फ़ाइल के साथ अपने इनपुट ओवरराइट नहीं करेगा? –

5

आपको वास्तव में इसके लिए sed का उपयोग नहीं करना चाहिए। यह प्रश्न हास्यास्पद रूप से अक्सर प्रतीत होता है, और ऐसा लगता है कि यह बहुत ही अजीब लगता है, क्योंकि सामान्य समाधान इतना छोटा है, ऐसा लगता है कि लोग यह जानना चाहते हैं कि कैसे इसे sed, और अजगर में, और रूबी आदि में करना है। ।

#!/bin/sh -e 
in=${1?No input file specified} 
mv $in ${bak=.$in.bak} 
shift 
"[email protected]" < $bak > $in 

एक निष्पादन योग्य फ़ाइल नाम inline में अपने रास्ते में रखो कि, और फिर समस्या सामान्य रूप में हल किया जाता है: यदि आप एक इनपुट पर काम करते हैं और इसे अधिलेखित एक फिल्टर करना चाहते हैं, निम्नलिखित सरल स्क्रिप्ट का उपयोग। उदाहरण के लिए:

inline input-file sed -e s/foo/bar/g 

अब, आप एक से अधिक बैकअप रखने के लिए, या तर्क जोड़ना चाहते हैं, तो आपको कुछ विकल्प बैकअप योजना के नामकरण, या जो कुछ भी बदलने के लिए है, तो आप एक ही स्थान पर ठीक करें। perl के साथ फ़ाइल में प्रोसेस करते समय बैकअप फ़ाइल पर 1-अप काउंटर प्राप्त करने के लिए कमांड लाइन विकल्प क्या है? ruby के साथ क्या? क्या विकल्प gnu-sed के लिए अलग है? awk इसे कैसे संभालता है? यूनिक्स का पूरा friggin 'बिंदु यह है कि उपकरण केवल एक चीज करते हैं। बैकअप फ़ाइलों के लिए तर्क को संभालना दूसरी बात है, और इसे बाहर निकालने की आवश्यकता है। यदि आप किसी टूल को कार्यान्वित कर रहे हैं, तो बैकअप फ़ाइलों को बनाने के लिए तर्क जोड़ें। अपने उपयोगकर्ताओं को इसके लिए एक दूसरा उपकरण उपयोग करने के लिए कहें। एकीकरण खराब है। मॉड्यूलरिटी अच्छा है। वह यूनिक्स तरीका है।

ध्यान दें कि इस स्क्रिप्ट में कई समस्याएं हैं।उदाहरण के लिए, इनपुट फ़ाइल की अनुमति/मोड बदला जा सकता है। मुझे यकीन है कि असंख्य अन्य मुद्दे हैं। हालांकि, एक आवरण स्क्रिप्ट में बैकअप तर्क रख कर, आप इन सभी मुद्दों को स्थानीय बनाना और जब तक python जगह में फ़ाइल रहता है और inode परिवर्तन नहीं होता है, चिंता करने की sed फ़ाइलों और परिवर्तन मोड अधिलेखित कर देता है कि नहीं है (मैं बनाया उन दो मामलों अप, बिंदु और किया जा रहा है कि नहीं सभी उपकरण, एक ही तर्क का उपयोग करेगा, जबकि आवरण स्क्रिप्ट है।)

+0

धन्यवाद, मुझे स्क्रिप्ट पसंद है और इसे मेरे स्वाद #!/Bin/sh -e = $ { 1? कोई इनपुट फ़ाइल निर्दिष्ट} $ mv "में $" {बक = in.bak} पारी "$ @" < "$bak" > && rm "$ बक" में $ || mv "$ बक" "", में –

+2

मैं असहमत $ यदि 'sed' यह करने के लिए एक समारोह है, तो मुझे कोई कारण नहीं यह करने के लिए नहीं देख पा रहे। ऐसा लगता है कि वह क्या चाहता है। – markzz

+0

@MarkWeiman समस्या यह है कि "sed" में वह फ़ंक्शन नहीं है। Sed का एक विशेष कार्यान्वयन उस फ़ंक्शन का समर्थन करता है, और जैसे ही आप अपनी स्क्रिप्ट को उस मशीन पर ले जाने का प्रयास करते हैं जो एक अलग कार्यान्वयन का उपयोग करता है, स्क्रिप्ट ब्रेक करता है। –

5

आप यथा-स्थान संपादन के लिए झंडा मैं उपयोग कर सकते हैं के लिए -e सामान्य स्क्रिप्ट अभिव्यक्ति निर्दिष्ट करना:

sed -i -e 's/pattern_to_search/text_to_replace/' file.txt 

एक निश्चित पैटर्न से मेल खाने वाली रेखाओं को हटाने के लिए सरल वाक्यविन्यास का उपयोग कर सकते हैं। सूचना झंडा:

sed -i '/pattern_to_search/d' file.txt 
+0

यह भी तरह तो file.txt-ए मूल फ़ाइल की एक प्रतिलिपि बनाता है पर अपने मैक, क्यों? – SuperUberDuper

+0

क्या आप -i और -e के बीच एक जगह छोड़ रहे हैं? क्योंकि अन्यथा यह बैकअप के लिए SUFFIX के रूप में विचार करेगा। सेड की मदद -i: '-i [SUFFIX], --in-place [= SUFFIX] फ़ाइलों को संपादित करने के लिए विवरण दिखाती है (यदि SUFFIX आपूर्ति की जाती है तो बैकअप बनाता है)' मैंने अभी अपनी लिनक्स मशीन पर इसका परीक्षण किया और ठीक काम करता है। – Tiago

संबंधित मुद्दे