मैं फ़ाइल में एक शब्द के साथ कई पंक्तियों को कैसे बदलूं (inplace प्रतिस्थापित)?


9

मेरी filenameफ़ाइल की सामग्री इस प्रकार है (उदाहरण के लिए):

My block of line starts from here 
START
First line
second line
third line
END
and end to here for example.

मैं उदाहरण के लिए, केवल एक शब्द के बीच STARTऔर उसके ENDसाथ लाइनों के ब्लॉक को बदलना चाहता हूं SINGLEWORD। नीचे की तरह:

My block of line starts from here 
SINGLEWORD
and end to here for example.

मैं इस कमांड का उपयोग करके लाइनों के अपने ब्लॉक को पा सकता हूं:

grep -Pzo "START(.|\n)*END" filename

और कमांड के ऊपर चलने का परिणाम इस प्रकार होगा:

START
First line
second line
third line
END

तब मैंने सभी लाइनों को एक लाइन में संयोजित करने के लिए इस कमांड का उपयोग किया:

LAST_RESULT | sed -e :a -e '/$/N; s/\n/ /; ta'

तब मुझे यह परिणाम मिलेगा:

START First line second line third line END

और अपने अंतिम आदेश के साथ LAST_RESULTS | sed 's/.*/SINGLEWORD/'मैं उन्हें बदल देता "SINGLEWORD"हूं और मुझे यह परिणाम मिलता है।

SINGLEWORD

अब मुझे जो चाहिए वह है: मैं इस कमांड (या आपके सुझाव कमांड) का उपयोग कैसे कर सकता हूं और "SINGLEWORD" शब्द के लिए लाइनों के अपने ब्लॉक को (जगह में) बदल सकता हूं? और अंतिम परिणाम इस फाइल की तरह होगा:

My block of line starts from here 
SINGLEWORD
and end to here for example.

जवाबों:


14

इसमें बहुत आसानी से किया जा सकता है perl:

$ perl -i -p0e 's/START.*?END/SINGLEWORD/s' file
$ cat file
My block of line starts from here 
SINGLEWORD
and end to here for example. 

व्याख्या

-0 शून्य करने के लिए लाइन विभाजक सेट करता है

-p-eप्रत्येक पंक्ति द्वारा दी गई स्क्रिप्ट को लागू करें और उस रेखा को प्रिंट करें

Regexp संशोधक:

  • /sस्ट्रिंग को सिंगल लाइन मानें। यही है, .किसी भी चरित्र से मेल खाने के लिए बदलें , यहां तक ​​कि एक नई पंक्ति, जो आम तौर पर यह मेल नहीं खाती।

क्यों ?:

  • डिफ़ॉल्ट रूप से, एक परिमाणित उप-समूह "लालची" है, अर्थात, यह बाकी के पैटर्न से मेल खाने के लिए अनुमति देते हुए भी कई बार संभव के रूप में (विशेष रूप से शुरुआती स्थान दिए गए) से मेल खाएगा। यदि आप चाहते हैं कि यह न्यूनतम समय की संख्या से मेल खाए, तो क्वांटिफायर का पालन करें ?

@ कसया: प्रयोग sedकरना संभव है लेकिन शायद पढ़ने में कठिन हो (इस सवाल पर गौर करें )
सिल्वेन पिनेउ

एक और क्योंकि मेरे START और END पैटर्न विशेष वर्ण (है /, *, ?उस में) और ये सिर्फ उदाहरण हैं। और क्या आप अपने आदेश की व्याख्या कर सकते हैं।
α atsнιη

@KasiyA आप के साथ \ ऐसे वर्ण बच सकते हैं (वास्तव में साथ के रूप में sed): \/, \*,\?
सिल्वेन पिनाओ

@ कसिया मैंने कोशिश की perl -i -p0e 's/\/\*.*?\*\//SINGLEWORD/sm'। यह काम करना चाहिए
सिल्वेन पिनेउ

@ कासिया मुझे लगता है कि मैं अब स्पष्टीकरण के साथ काम कर रहा हूं;)
सिल्वेन पिनेउ

14

मैं सोच रहा था कि क्या यह बिना संभव है perl, pythonऔर अन्य। और मैंने इस समाधान का उपयोग कर पाया sed:

$ sed ':a;N;$!ba;s/START.*END/SINGLEWORD/g' filename

स्पष्टीकरण:

  1. : 'a' लेबल बनाएँ
  2. N अगली पंक्ति को पैटर्न स्पेस में जोड़ता है
  3. $! यदि अंतिम पंक्ति नहीं है , बा शाखा (लेबल) पर जाएँ 'a'
  4. एस स्थानापन्न , /START.*END/द्वारा SINGLEWORD, / जी (के रूप में यह कर सकते हैं कई बार के रूप में) वैश्विक मैच

यह यहां पाया गया था ।

@ कासिया, शुक्रिया मैंने बहुत सी रोचक बातें सीखीं!

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