फाइलों में मल्टीलाइन स्ट्रिंग बदलें


17

मेरे पास कई फाइलें हैं जिन्हें मैं एक मल्टी-लाइन स्ट्रिंग को दूसरे मल्टी-लाइन स्ट्रिंग के साथ अद्यतन करना चाहता हूं। की तर्ज पर कुछ:

* Some text, 
* something else
* another thing

और मैं इसे बदलना चाहता हूं:

* This is completely
* different text

इसका परिणाम यह होगा कि प्रतिस्थापन के बाद फ़ाइल में पहले खंड का पाठ होता है, जिसमें अब दूसरा स्ट्रिंग (शेष फ़ाइल अपरिवर्तित होता है) होगा।

समस्या का हिस्सा यह है कि मुझे फाइल की सूची को फाइल सिस्टम में अपडेट करना है। मुझे लगता है कि मैं उसके लिए grep का उपयोग कर सकता हूं (हालांकि फिर से मल्टीलाइन स्ट्रिंग्स के साथ ऐसा करना आसान नहीं है) फिर इसे शायद sed में पाइप करें?

क्या इसे करने का कोई आसान तरीका है? Sed एक विकल्प है लेकिन यह अजीब है क्योंकि मुझे \ n आदि को जोड़ना है। क्या यह कहने का कोई तरीका है कि "इस फाइल से इनपुट लें, इसे उन फाइलों में मिलाएं, फिर इसे इस दूसरी फाइल की सामग्री से बदल दें"? जरूरत पड़ने पर मैं अजगर का उपयोग कर सकता हूं, लेकिन मैं कुछ त्वरित और सरल चाहता हूं, इसलिए अगर कोई उपयोगिता उपलब्ध है, तो मैं इसका उपयोग खुद की स्क्रिप्ट लिखने के बजाय (जो मुझे पता है कि कैसे करना है) करना चाहिए।


आपको शायद इसके लिए पर्ल का इस्तेमाल करना चाहिए। stackoverflow.com/questions/1030787/…
ओरियन

3
तो आप मैच करना चाहते हैं some text, something else another thingया नहीं, यह कई लाइनों तक फैला है? या आप केवल मैच करना चाहते हैं some text,\nsomething else\nanotherthing?
सुबह

2
अपने प्रश्न को संपादित करें और स्पष्ट करें कि प्रत्येक फ़ाइल की सामग्री क्या है और वांछित आउटपुट क्या है।
जिम्मीज

स्ट्रिंग कई लाइनों को फैलाती है। मैं मैच / रिप्लेस करते समय व्हाट्सएप की अवहेलना करता हूं क्योंकि यह सब बिल्कुल एक जैसा नहीं हो सकता है, लेकिन अगर मैं सिर्फ 1-1 मैच (नए अंक और सभी) करता हूं तो यह बहुत बड़ी बात नहीं है।
ventsyv

जवाबों:


12

एक या अधिक इनपुट फ़ाइलों में फ़ाइल "नई" की सामग्री द्वारा "कुछ ... \ n ... बात" को प्रतिस्थापित करें

perl -i -p0e 's/Some.*?thing\n/`cat new`/se' input.txt ...
  1. -i सीधे इनपुट बदलने के लिए
  2. -p0 स्लप इनपुट फ़ाइल फ़ाइल और अंत में इसे प्रिंट करें
  3. s/regexp/.../s regexp में .है.|\n
  4. s/.../exp/e द्वारा हटाया गया eval(exp)
  5. नया - प्रतिस्थापन पाठ वाली एक फ़ाइल (यह पूरी तरह से है ... अलग पाठ)
  6. यदि उपयोगी हो तो आप मूल पाठ का विस्तार कर सकते हैं s/Some text\n...\n...thing\n/...

मैं उस फ़ाइल की सामग्री (मल्टी-लाइन) देखने के लिए "पहले" नामक फ़ाइल के साथ कैसे कर सकता हूं? मैंने कोशिश की लेकिन बात नहीं बनी।
Kvothe

@ क्वोट, हमें और अधिक विवरणों की आवश्यकता है ... यह मानते हुए कि "पहले" के पास कोई विशेष वर्ण नहीं है, आप कोशिश कर सकते हैंperl -i -p0e ' $b= `cat before`; s/$b/Some thing\n/se' input.txt ...
जजो

और "पहले" को संभालने पर 'और' को छोड़कर सभी विशेष वर्ण (नई लाइनें, स्लैश, ब्रैकेट) शामिल हैं।
क्वाथ

5
sed -e :n -e '$!N;/\n.*\n/!{$!bn
};  s/some text,\n* *something else\n* *another thing/this is completely\
different text/;P;D' <infile

मुझे डर है कि आप एक मुश्किल समय के समाधान के साथ आने वाले हैं जो आपको तब तक सूट करता है जब तक कि आप समस्या का एक ठोस विवरण नहीं निकालते हैं - लेकिन यही क्यूए के लिए सबसे उपयुक्त है, जैसा कि मैं इसे देखता हूं। शायद यह आपको एक विचार देगा - यह हमेशा एक समय में पैटर्न लाइन में 3 लाइनें रखेगा - एक 2 लाइन लुकहैड के साथ - जबकि इनपुट फ़ाइल के माध्यम से एक बार में केवल एक पंक्ति को आगे खिसकाते हुए।

यह आपके तार से मेल खाने में सक्षम होना चाहिए चाहे वह कई पंक्तियों तक फैला हो या नहीं - तीन तक, अर्थात। लेकिन प्रतिस्थापन में उस प्रावधान को प्रतिबिंबित करने के लिए कोई प्रावधान नहीं हैं - यह हमेशा लिखित रूप में दो पंक्तियों तक फैला होता है।


0

मजबूत करने के लिए नहीं (क्योंकि दूसरी स्ट्रिंग को शेच न करें लेकिन इसे निपटाना आसान है) और पॉज़िक्स कंप्लेंट नहीं हो सकता है लेकिन बहुत सरल है:

sed '/^Some text/{:1;/another thing$/!{N;b 1}
     s/.*/this is completely\ndifferent text/g}' input.txt

पहले कमांड कुछ टेक्स्ट से लाइनें जोड़ते हैं जब तक कि कोई दूसरी चीज नहीं मिल जाती है तब दूसरी लाइन इसे दूसरे टेक्स्ट में बदल देती है।

नोट सीमा यह है कि कुछ पाठ को हमेशा किसी अन्य चीज का पालन ​​करना चाहिए ।


समस्या यह है कि स्ट्रिंग 2 पंक्तियों (एक दर्जन या अधिक तक) हो सकती है और इसमें अन्य सामान हो सकते हैं जिन्हें
बचाना पड़

@ventsyv लाइनों या विभाजकों की संख्या के साथ कोई समस्या नहीं है - स्क्रिप्ट केवल शुरुआत और अंत की जांच करती है। यह काफी पर्याप्त है IF प्रारंभ स्ट्रिंग बाह्य रूप से पाठ को बदलने के लिए चिह्नित कर सकता है । यदि आपका बेहतर प्रदर्शन सही उदाहरण प्रस्तुत करने के लिए इनपुट उदाहरण नहीं है।
कोस्टास
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.