फ़ाइल से दो पैटर्न के बीच की सामग्री को कैसे बदलें?


9

मैंने फ़ाइल का निम्नलिखित प्रारूप बनाया है:

<common>
fitnes=0
genetic=1
method=0
</common>
<inputs>
foo=bar
bar=foo
</inputs>
<limits>
balance=200.00
</limits>

और मैं जो कुछ भी है उसे हटाना चाहता हूं <inputs>और </inputs>(पैटर्न-सेल्फ को छोड़कर) और इसे दूसरी फाइल (उदाहरण के लिए foo.txt) की सामग्री से प्रतिस्थापित करना चाहता हूं । साथ दूसरे शब्दों लाइनों में foo=barऔर bar=fooएक अन्य सामग्री के साथ प्रतिस्थापित किया जाएगा।

संभवतः यह एक बहु-पंक्ति मैच को हटाने के समान हो सकता है , जैसे:

:g/<inputs/,/inputs>/d

लेकिन मैं के साथ यकीन नहीं है क्या मैं बदलना चाहिए dआदेश एक और फ़ाइल की सामग्री डालने के लिए में है, लेकिन मैं मिलान पैटर्न रखना चाहते हैं।

HTML टैग की आंतरिक सामग्री को हटाने के लिए इसी तरह का दृष्टिकोण होगा , जैसे

:/<inputs>/norm vitd

लेकिन फिर मुझे नहीं पता कि आप इसमें फ़ाइल से सामग्री कैसे जोड़ेंगे।

आदर्श रूप से मैं एक लाइनर खोजने की कोशिश कर रहा हूं, क्योंकि यह किसी अन्य स्क्रिप्ट का हिस्सा होगा।

मैं उसे कैसे प्राप्त कर सकता हूं?

जवाबों:


10

इस तरह से एक अभिव्यक्ति के परिणाम के साथ एक पैटर्न को बदलने के लिए एक प्रतिस्थापन का उपयोग किया जा सकता है:

:keeppatterns %s;<inputs>\zs\_.\{-}\ze</inputs>;\=insert(readfile('test.txt'), '')

देख :help sub-replace-expression

ध्यान दें कि कमांड को खोज इतिहास में कुछ भी जोड़ने से keeppatternsरोकता है substituteऔर "अंतिम खोज पैटर्न रजिस्टर" को संरक्षित करता है - देखें :help "/। यह अनावश्यक रूप से आदेश संशोधक के साथ विम के वैश्विक राज्य को संशोधित करने से स्क्रिप्ट को रोकने के लिए अच्छा व्यवहार है keepalt, keepjumps, lockmarks, keepmarks, और keeppatterns


5

गैरी से एक वैकल्पिक दृष्टिकोण यह है:

:g/^<inputs>/+,/^<\/inputs>/-d|-r dummy

जो पहले दिए गए पैटर्न में सब कुछ हटा देता है, :rफ़ाइल डमी से डेटा पढ़ने के लिए कमांड का उपयोग करता है । अब अगर आपको <input>/</input>पैटर्न के बीच की रेखाओं से फ़ाइल नाम निकालने की आवश्यकता है , तो यह एक लिट्टी बिट और अधिक जटिल हो जाती है।


4

यह काम करने के लिए लगता है, कम से कम एक यूनिक्स प्रणाली पर:

:/<inputs>/+1,/<\/inputs>/-1!cat foo.txt

यह का उपयोग करता है {range}!{filter}के बाद एक से लाइनों को फिल्टर करने के आदेश <inputs>से पहले एक के लिए </inputs>बाहरी कार्यक्रम के माध्यम से cat foo.txt। इस मामले में, catइसके मानक इनपुट को अनदेखा करता है, इसलिए मूल लाइनें हटा दी जाती हैं और फ़ाइल की सामग्री द्वारा प्रतिस्थापित की जाती हैं foo.txt

देख:

:help :range!
:help cmdline-ranges

2

मुझे लगता है कि एक मैक्रो एक आसान तरीका होगा। खासकर, यदि आपके पास ऐसा करने के लिए विभिन्न स्थान हैं।

  1. केवल उन 2 फाइलों को खुला रखें।
  2. अब पहली फ़ाइल में qa,( aरिकॉर्ड नाम है) रिकॉर्डिंग शुरू करें।
  3. शुरुआत पैटर्न, प्रेस के लिए खोज नीचे है, तो प्रेस Ctrl- v,, अंत पैटर्न को खोजने प्रेस अप । अब जिस हिस्से को आप डिलीट करना चाहते हैं वह सिलेक्ट हो गया है। इसे मिटाओ।
  4. स्थिति का उपयोग करके चिह्नित करें ma( aचिह्न नाम है) और फ़ाइल को सहेजें।
  5. 2 फाइल पर जाएं, :b2कमांड के द्वारा और इसी तरह अपने स्टार्ट / एंड मापदंड के अनुसार भाग का चयन करें।
  6. aउस बिंदु पर जाने के लिए इस फाइल प्रेस पर वापस आएं । वहाँ चिपकाएँ p
  7. अंत मानदंड के लिए फिर से खोजें, और इसे फिर से न मारने के लिए अनुभाग को पार करें।
  8. दबाकर पुनरावृत्ति छोड़ें q
  9. द्वारा की संख्या को दोहराएं 40@a

1
सुझाव के लिए धन्यवाद, यह ठीक है, लेकिन यह इस विशेष मामले में मदद नहीं करेगा, क्योंकि मैं exस्क्रिप्ट के हिस्से के रूप में गैर-संवादात्मक समाधान की तलाश कर रहा हूं जहां मैं निर्दिष्ट कर सकता हूं कि उपयोगकर्ता इनपुट तर्कों के आधार पर कौन सी फ़ाइल सम्मिलित करें।
kenorb

1

यदि यह XML को गैर- XML ​​उपकरण के साथ पार्स करने का एक और प्रयास है, तो नहीं।

यहाँ समाधान मान्य हैं, लेकिन इरादा नहीं हो सकता है। यदि XML एक अच्छी तरह से नामांकित स्रोत से नहीं है, तो आप टैग में एस्केप, सीडीएटीए या सफेद रिक्त स्थान प्राप्त कर सकते हैं!

तो vi में कमांड से xsltproc उस से निपट सकते हैं।


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