मैं बहुस्तरीय टेक्स्ट फ़ाइल में नेस्टेड कर्ली ब्रैकेट के बीच के सभी टेक्स्ट को कैसे हटा सकता हूं?


9

यह प्रश्न आता है कि मैं एक बहु-पाठ पाठ फ़ाइल में घुंघराले कोष्ठक के बीच सभी पाठ को कैसे हटा सकता हूं? (बस एक ही है, लेकिन घोंसले के शिकार के लिए आवश्यकताओं के बिना)।

उदाहरण:

This is {
{the multiline
text} file }
that wants
{ to {be
changed}
} anyway.

बन जाना चाहिए:

This is 
that wants
 anyway.

क्या यह किसी प्रकार की एक-लाइन बैश कमांड (awk, sed, perl, grep, cut, tr ... etc) के साथ करना संभव है?

जवाबों:


13
$ sed ':again;$!N;$!b again; :b; s/{[^{}]*}//g; t b' file3
This is 
that wants
 anyway.

स्पष्टीकरण:

  • :again;$!N;$!b again

    यह पूरी फाइल में पढ़ता है।

    :againएक लेबल है। Nअगली पंक्ति में $!Nपढ़ता है और अगली पंक्ति में इस शर्त पर पढ़ता है कि हम पहले से ही अंतिम पंक्ति में नहीं हैं। इस शर्त पर लेबल पर $!b againवापस जाएं againकि यह अंतिम पंक्ति नहीं है।

  • :b

    यह एक लेबल को परिभाषित करता है b

  • s/{[^{}]*}//g

    यह तब तक ब्रेसिज़ में पाठ को हटाता है जब तक कि टेक्स्ट में कोई आंतरिक ब्रेस नहीं होता।

  • t b

    यदि उपरोक्त स्थानापन्न आदेश में परिवर्तन हुआ है, तो लेबल पर वापस जाएं b। इस प्रकार, सभी ब्रेस-समूहों को हटाने तक स्थानापन्न कमांड को दोहराया जाता है।


3

एक पर्ल दृष्टिकोण:

$ perl -F"" -a00ne 'for (@F){$i++ if /{/; $i||print; $i-- if /}/}' file
This is 
that wants
 anyway

व्याख्या

  • -a: सरणी -Fमें दिए गए फ़ाइल सीमांकक पर स्वचालित विभाजन को चालू करता है @F
  • -F"": इनपुट क्षेत्र विभाजक को खाली करने के लिए सेट करता है, जिसके परिणामस्वरूप प्रत्येक तत्व @Fइनपुट वर्णों में से एक होगा।
  • -00: "पैराग्राफ मोड" चालू करें, जहां एक "लाइन" को दो लगातार न्यूलाइन वर्णों के रूप में परिभाषित किया गया है। इसका मतलब है कि इस मामले में पूरी फाइल को एक ही लाइन के रूप में माना जाएगा। यदि आपकी फ़ाइल में कई अनुच्छेद हो सकते हैं और कोष्ठक कई अनुच्छेदों को जोड़ सकते हैं, तो -0777इसके बजाय उपयोग करें ।
  • -ne: एक इनपुट फ़ाइल पढ़ें और -eप्रत्येक पंक्ति द्वारा दी गई स्क्रिप्ट को लागू करें ।

स्क्रिप्ट ही वास्तव में काफी सरल है। एक काउंटर को हर बार एक-एक {करके बढ़ाया जाता है और हर एक के लिए एक-एक करके देखा जाता है }। इसका मतलब है कि जब काउंटर 0 है, हम कोष्ठक के अंदर नहीं हैं और इसे प्रिंट करना चाहिए:

  • for (@F){}: प्रत्येक तत्व के लिए ऐसा करें @F, पंक्ति में प्रत्येक वर्ण।
  • $i++ if /{/;: $iयह चरित्र एक होने पर वेतन वृद्धि{
  • $i||print;: तब तक प्रिंट करें जब तक $iकि सेट न हो जाए (0 काउंट अनसेट)।
  • $i-- if /}/: $iअगर यह चरित्र ए है तो एक से घटाव}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.