Https://vi.stackexchange.com/a/818/227 पर उत्तर के समान , आप वैश्विक कमांड का उपयोग कर सकते हैं।
इसके साथ आप एक पैटर्न से मेल खाते लाइनों की खोज करने के लिए विम को निर्देश दे सकते हैं, और फिर उस पर कमांड कर सकते हैं।
आपके मामले में, आप "स्तर N:" से शुरू होने वाली लाइनों के लिए पाठ को प्रस्तुत करना चाहते हैं, इसलिए हमारी वैश्विक कमांड हो सकती है
:g/^Level \d:/{COMMANDS}
कमांड के लिए स्थानापन्न कमांड (नियमित अभिव्यक्ति प्रतिस्थापन) का उपयोग करना
आदेश अधिक मजेदार है। मैं आमतौर पर इस तरह से सामान के लिए एक नियमित अभिव्यक्ति प्रतिस्थापन करना पसंद करता हूं, क्योंकि चर का उपयोग करना आसान है।
अपने प्रश्न के लिए उदाहरण
:let i = 1 | g/^Level \d:/s/^/\=printf("%02d ", i)/ | let i = i+1
यह काम किस प्रकार करता है
प्रतिस्थापन कमांड के प्रतिस्थापन खंड में एक अभिव्यक्ति हो सकती है।
पहली चीज़ जो हम करेंगे, वह है एक वेरिएबल i
जो शुरुआती संख्या है। मैंने 1 चुना, लेकिन कोई भी संख्या क्या करेगी।let i = 1
फिर हम अपना ग्लोबल कमांड चलाते हैं, जो हमें मैच्योर लाइनों पर एक्शन करने के लिए सेट करता है। g/^Level \d:/
हमारे पास हमारे वैश्विक कमांड में मूल्य और इंसर्बेशन कमांड और लेट कमांड का उपयोग करके हमारे काउंटर को बढ़ाना होगा।s/^/\=printf("%02d ", i)/ | let i = i+1
प्रतिस्थापन कमांड की नियमित अभिव्यक्ति लाइन की शुरुआत का पता ^
लगाती है और इसे एक अभिव्यक्ति के साथ बदल देती है, और हमारी अभिव्यक्ति एक स्वरूपित प्रिंट का परिणाम होगी। सी लैंग्वेज की तरह, विम का प्रिंटफ फॉर्मेटिंग पैरामीटर्स लेता है। %02d
इसका मतलब है कि एक तर्क को रूपांतरित करें क्योंकि यह एक दशमलव संख्या थी d
, जिसमें कम से कम 2 स्थान थे 2
और 0 के साथ पैड था 0
। विवरण और अन्य रूपांतरण विकल्पों के लिए (फ्लोटिंग पॉइंट फॉर्मेटिंग सहित), देखें :help printf
। हम प्रिंटफ को अपना काउंटिंग वैरिएबल देते हैं i
और यह हमें 01
पहली बार, 02
दूसरी बार आदि देता है। यह प्रतिस्थापन कमांड द्वारा लाइन की शुरुआत को बदलने के लिए उपयोग किया जाता है, प्रभावी रूप से शुरुआत में प्रिंटफ के परिणाम को सम्मिलित करता है।
ध्यान दें कि मैंने d: के बाद एक स्थान रखा है "%02d "
। आपने प्रश्न में यह नहीं पूछा (और मैंने उदाहरण आउटपुट नहीं देखा), लेकिन मुझे संदेह था कि आप शब्द "स्तर" से संख्या को अलग करना चाहते थे। L में लेवल के ठीक बगल में डाले गए नंबर को प्रिंट करने के लिए दिए गए स्ट्रिंग से स्पेस निकालें।
अंत में, वह let i = i + 1
प्रत्येक प्रतिस्थापन के बाद हमारे काउंटर को बढ़ाता है।
यह आम तौर पर मनमाने ढंग से कार्यात्मक डेटा के साथ अन्य मानदंडों द्वारा मेल खाने वाली लाइनों के हिस्सों को बदलने के लिए लागू किया जा सकता है।
संयुक्त सामान्य आदेशों का उपयोग करना
यह सरल सम्मिलन या जटिल संपादन के लिए अच्छा है। स्थानापन्न की तरह, हम मिलान करने के लिए वैश्विक का उपयोग करेंगे, लेकिन नियमित अभिव्यक्ति प्रतिस्थापन के बजाय, हम संचालन की एक श्रृंखला निष्पादित करेंगे जैसे कि उपयोगकर्ता द्वारा टाइप की गई हो।
अपने प्रश्न के लिए उदाहरण
:let i = 1 | g/^Level \d:/execute "normal! I" . printf("%02d ", i) | let i = i+1
यह काम किस प्रकार करता है
उपयोग किए गए मान विकल्प के समान हैं (हम इसे अभी भी प्रिंट करने के लिए हमारे नंबर को प्रारूपित करने के लिए उपयोग कर रहे हैं ताकि इसे 2 अंकों के साथ 0 गद्देदार बनाया जा सके), लेकिन ऑपरेशन अलग है।
यहां हम निष्पादित कमांड का उपयोग करते हैं, जो एक स्ट्रिंग लेता है और स्ट्रिंग को पूर्व कमांड ( :help :exe
) के रूप में चलाता है । हम एक स्ट्रिंग का निर्माण करते हैं जो हमारे डेटा के साथ "सामान्य!" को जोड़ती है, जो "सामान्य! I01" पहली बार और "सामान्य! I02" दूसरी बार होगा।
normal
आदेश प्रदर्शन संचालन के रूप में सामान्य मोड में है। इस उदाहरण में, हमारा सामान्य कमांड है I
, जो लाइन की शुरुआत में सम्मिलित होता है। यदि हमने इसका उपयोग किया था तो dd
यह लाइन को हटा देगा, o
मिलान वाली लाइन के बाद एक नई लाइन खोलेगा। यह ऐसा है जैसे कि आपने I
सामान्य मोड में खुद को टाइप किया (या कोई अन्य ऑपरेशन)। हम प्रयोग !
के बाद normal
सुनिश्चित करें कि कोई मैपिंग हमारे रास्ते में बनाने के लिए। देख लो :help :normal
।
फिर क्या डाला जाता है, हमारे प्रिंटफ का मूल्य है, जैसा कि विकल्प का उपयोग करने के पहले उदाहरण में है।
यह विधि regex की तुलना में कट्टर हो सकती है, क्योंकि आप ऐसी चीजें कर सकते हैं execute "normal! ^2wy" . i . "th$p"
, जो पाठ की शुरुआत में ^
जाएंगे, 2 शब्दों को आगे बढ़ाएं 2w
, ith 'h' वर्ण तक यैंक y" . i . "th
, पंक्ति के अंत तक जाएं $
, और पेस्ट करें p
।
यह लगभग एक मैक्रो को चलाने जैसा है, लेकिन वास्तव में एक रजिस्टर का उपयोग नहीं करता है और किसी भी भाव से तारों को जोड़ सकता है। मुझे यह बहुत शक्तिशाली लगता है।
दृष्टिकोण जहां प्रत्येक स्तर का अपना काउंटर है
आप चाहते हैं कि प्रत्येक स्तर को अपना काउंटर मिल सके। यदि आप समय से पहले अधिकतम स्तर जानते हैं, तो आप निम्न कार्य कर सकते हैं (सबसे बड़ा स्तर खोजने के लिए अतिरिक्त कोड जोड़ना बहुत कठिन नहीं हो सकता है, लेकिन यह उत्तर बहुत लंबा कर देगा। यह तब तक लंबा हो रहा है)।
सबसे पहले, मैं मुक्त कर देता हूं, अगर हम पहले ही इसे पूर्णांक के रूप में उपयोग करते हैं। हम इसे सूची में नहीं बदल सकते, हमें इसे इस तरह से बनाना होगा।
:unlet! i
अगला, आइए मैं एक सूची बनाता हूं जिसमें स्तरों की संख्या होती है। आपने अपने प्रश्न में 2 दिखाए हैं, लेकिन इसके मज़े के लिए 10 मान लेते हैं। चूंकि सूची अनुक्रमण 0 आधारित है, और मैं आपकी सूची की तरह 1 के लिए सही को परेशान नहीं करना चाहता, हम सिर्फ पर्याप्त तत्व (11) बनाएंगे और कभी भी 0 अनुक्रमणिका का उपयोग नहीं करेंगे।
:let j = 0
:let i = []
:while j < 11 | let i += [1] | let j += 1 | endwhile
अगला, हमें स्तर संख्या प्राप्त करने का एक तरीका चाहिए। सौभाग्य से, विकल्प एक फ़ंक्शन के रूप में भी उपलब्ध है, इसलिए हम इसे अपनी लाइन देंगे और स्तर संख्या निकालेंगेsubstitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")
चूंकि अब मैं 11 1
एस की सूची (प्रत्येक सूचकांक हमारे स्तर के लिए काउंटर है), हम अब इस प्रतिस्थापन के परिणाम का उपयोग करने के लिए उपरोक्त उदाहरणों में से किसी एक को समायोजित कर सकते हैं:
स्थानापन्न आदेश:
:unlet! i | unlet! j | let j = 0 | let i = [] | while j < 11 | let i += [1] | let j += 1 | endwhile
:g/^Level \d:/let ind=str2nr(substitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")) | s/^/\=printf("%02d ", i[ind])/ | let i[ind] += 1
सामान्य आदेश:
:unlet! i | unlet! j | let j = 0 | let i = [] | while j < 11 | let i += [1] | let j += 1 | endwhile
:g/^Level \d:/let ind=str2nr(substitute(getline("."), "^Level \\(\\d\\):.*", "\\=submatch(1)", "")) | execute "normal! I" . printf("%02d ", i[ind]) | let i[ind] += 1
उदाहरण इनपुट:
Level 1: stuff
Level 1: Stuff
Some text
Level 3: Other
Level 1: Meh
Level 2: More
उदाहरण आउटपुट:
01 Level 1: stuff
02 Level 1: Stuff
Some text
01 Level 3: Other
03 Level 1: Meh
01 Level 2: More