हर 4 लाइनों को उल्टा कैसे करें?


13

सबसे पहले, यहाँ मेरी पहली पोस्ट होने के साथ, मैं सिर्फ इतना कहना चाहूँगा कि मैंने VIM को एक महान उपकरण पाया है और यहाँ मंच को सवालों के जवाब खोजने में बहुत मददगार साबित होने के साथ, बहुत सारे मददगार लोग प्रदान करते हैं। अमूल्य सहायता। मैं अभी भी VIM के लिए बहुत नया हूँ, इसलिए बहुत कुछ जो मैंने इसके बारे में सीखा है वह यहाँ से आया है।

मेरा प्रश्न है: मुझे पता है कि किसी फ़ाइल में सभी पंक्तियों को कैसे उल्टा करना है: (g / ^ / m0 अन्य तरीकों से), लेकिन क्या किसी फ़ाइल में हर 4 पंक्तियों को उलटने का एक तरीका है, ताकि

line1
line2
line3
line4
line5
line6
line7
line8
...

हो जाता है

line4
line3
line2
line1
line8
line7
line6
line5
...

आप मान सकते हैं कि इस तरह की फाइलों में हमेशा एक से अधिक 4 लाइनें होंगी।


2
अपने "पीएस" के बारे में: यदि आप एक पंक्ति के सामने 4 रिक्त स्थान डालते हैं तो इसे कोड के रूप में व्याख्या की जाती है (आप पाठ का चयन कर सकते हैं और शीर्ष पर प्रारूप बटन का उपयोग कर सकते हैं)। आप शीर्ष पर पूछताछ आइकन पर अधिक जानकारी पा सकते हैं ।
mMontu

जवाबों:


15

विम विकी:Reverse में बताई गई कमांड का उपयोग इसके लिए किया जा सकता है ( इसे स्थायी करने के लिए आप इसे इसमें शामिल कर सकते हैं ):.vimrc

command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohl

तब आप हर चार लाइनों पर कमांड चलाने के लिए एक मैक्रो रिकॉर्ड कर सकते हैं:

qmV3j:Reverse<cr>4jq
1000@m

स्पष्टीकरण:

  • qm: सामान्य मोड में 'q' शुरू होता है (और रुक जाता है) दिए गए रजिस्टर में मैक्रो रिकॉर्ड करना (रजिस्टर 'm', इस मामले में, लेकिन यह कोई अन्य पत्र हो सकता है)
  • V: दृश्य मोड दर्ज करें और वर्तमान लाइन का चयन करें
  • 3j: अगली 3 पंक्तियों के लिए दृश्य चयन का विस्तार करें
  • :Reverse<cr>: चयनित लाइनों पर रिवर्स कमांड चलाएँ ( <cr>यहाँ enterकुंजी के लिए खड़ा है )
  • 4j: अगली अपरिवर्तित लाइनों पर जाएं
  • q: मैक्रो रिकॉर्ड करना बंद कर देता है
  • 1000@m: रजिस्टर 'एम' पर दर्ज मैक्रो को 1000 बार चलाएं (यदि आपकी फ़ाइल 4000 लाइनों से बड़ी है तो आप इस संख्या को बढ़ा सकते हैं)

संपादित करें:

जैसा कि टिप्पणियों में बताया गया है, आप एक गणना का उपयोग करने के बजाय एक पुनरावर्ती मैक्रो का उपयोग कर सकते हैं:

qmV3j:Reverse<cr>4jq
qM@mq
@m
  • qM: यदि रजिस्टर के लिए निर्दिष्ट qअपरकेस है तो मैक्रो को रजिस्टर में जोड़ दिया जाता है (जो तब भी उपयोगी होता है जब आपको पता चलता है कि जब आप किसी जटिल मैक्रो पर अंतिम चरण से चूक गए थे)
  • @m: रजिस्टर पर मैक्रो चलाएँ m
  • q: मैक्रो को जोड़ना बंद करें

मैक्रो के रूप में निर्मित होने के बावजूद, आप इसके लिए एक कमांड बना सकते हैं यदि यह आपके वर्कफ़्लो पर एक सामान्य कार्य है:

function! Reverse4()
   let reg_m = @m
   let @m = '<c-r><c-r>m'
   normal! @m
   let @m = reg_m
endfunction
command! Reverse4 call Reverse4()
  • function! Reverse4()/ endfunction: एक नए फ़ंक्शन को परिभाषित करता है
  • let reg_m = @m: रजिस्टर की वर्तमान सामग्री को बचाता है m
  • let @m = "<c-r><c-r>m": रजिस्टर में मैक्रो डालें m- ध्यान दें कि + के <c-r>लिए विम नोटेशन है और आपको इसे टाइप करना चाहिए , कॉपी / पेस्ट नहीं करना चाहिए , इसलिए आपकी लाइन समान होगी और इसमें एक विशेष वर्ण (^ M) होगाCtrlrlet @m = 'V3j:Reverse^M4j@m'
  • normal! @m: सामान्य कमांड अपने तर्क को चलाता है क्योंकि इसे सामान्य मोड में टाइप किया गया है, इसलिए यह पुनरावर्ती मैक्रो को चलाएगा
  • let @m = reg_m: रजिस्टर की सामग्री को पुनर्स्थापित करता है m, इसलिए आपको यह याद रखने की आवश्यकता नहीं है कि यह रजिस्टर इस फ़ंक्शन पर उपयोग किया जा रहा है और इसका उपयोग करने से बचें

  • command! Reverse4 call Reverse4(): इस फंक्शन के लिए एक नया कमांड बनाएं

अपनी आवश्यकताओं के आधार पर आप इसे बढ़ा सकते हैं, जैसे: कमांड और फ़ंक्शन के लिए एक तर्क पास करें ताकि यह 4 लाइनों के समूहों में तय होने के बजाय किसी भी संख्या में लाइनों के लिए काम करे।


1000@qहैक के बजाय , आप एक पुनरावर्ती मैक्रो का उपयोग भी कर सकते हैं qmqqm ... @mq@m:।
डोरकनॉब

जब मैंने "qmV3j: रिवर्स <cr> 4jq" चलाने की कोशिश की, तो उसने कहा "E492: एडिटर कमांड नहीं"। मुझसे कुछ गलत हो रहा होगा। मैं उपयोग कर रहा हूं - और केवल कभी उपयोग किया है - जीवीआईएम, वैसे। मुझे इसका उल्लेख करना चाहिए था।
सक्षमवासी

आह बुरा न मानें। मुझे यह समझ में आया - मैं "qmV3j:" से पहले टाइप नहीं कर रहा हूँ: "उल्टा <cr> 4jq" भाग। इसने काम कर दिया! बहुत बहुत धन्यवाद, mMontu। अगर मैं पूछ सकता हूं - मैं अपने .vimrc में ": रिवर्स" कमांड को कैसे शामिल करूं?
सक्षमवाशीसावेल्बा

3
@ablewasiereisawelba कमांड को स्थायी रूप से उपलब्ध कराने के लिए, बस लाइन command! -bar -range=% Reverse <line1>,<line2>g/^/m<line1>-1|nohlको अपने vimrc में कहीं लिखें ।
सगिनॉ

@saginaw ओह, मुझे नहीं पता था कि यह सीधा था। धन्यवाद।
सक्षमवाशीसावेल्बा

9

साथ के रूप में सब दोहराए कार्यों , आप कुछ एक बार बुनियादी आपरेशन संपादित साथ तो आप आसानी से इसे किसी मैक्रो को रिकॉर्ड करके समय की बहुत सारी कर सकते हैं कर सकते हैं, तो।

(इस मामले में मैं एक पुनरावर्ती मैक्रो का उपयोग करूंगा, लेकिन आप केवल एक गैर-पुनरावर्ती रिकॉर्ड कर सकते हैं और इसे कई बार हथौड़ा मारकर @@या एक गिनती का उपयोग करके वापस खेल सकते हैं ।)

ggqqqqqddjjpkddkkPjddpjj@qq@q

टूटा

  1. gg: फ़ाइल के प्रारंभ में जाएं।
  2. qqq: रजिस्टर साफ़ करें q। हम देखेंगे कि यह चरण 5 में क्यों आवश्यक है।
  3. qq: Q रजिस्टर करने के लिए मैक्रो रिकॉर्ड करना शुरू करें
  4. ddjjpkddkkPjddpjj: संचालन की एक श्रृंखला जो पहले चार लाइनों को हटाकर और उन्हें मैन्युअल रूप से चिपकाकर पुन: व्यवस्थित करती है। (यह पहली नज़र में जटिल हो सकता है देखो, लेकिन धोखा नहीं किया है यह बहुत ही बुनियादी सामान आप पहली बार 5 मिनट में सीखा है चाहते हैं कि या तो की। vimtutor: j, k, dd, p, P)
  5. @q: मैक्रो को बुलाओ! इस बिंदु पर, रजिस्टर qमें कुछ भी नहीं है (क्योंकि हमने इसे चरण 2 में मंजूरी दे दी है), इसलिए कुछ भी नहीं होगा।
  6. q: मैक्रो रिकॉर्ड करना बंद करो।
  7. @q: पुनरावर्ती मैक्रो को आवश्यक के रूप में कई बार पुन: चलाएँ।

एनबी उपरोक्त वांछित परिणाम नहीं देगा यदि फ़ाइल में कई लाइनें हैं जो चार से बिल्कुल विभाज्य नहीं हैं। मैक्रो को जल्दी बंद करने के लिए अगर चार लाइनें नहीं बची हैं, तो हमें एक विम-नॉर्मल-मोड कमांड को अंजाम देना होगा, जो विफल हो जाएगा, इससे पहले कि हम चरण 4 में संपादन लागू करना शुरू करें। हम इसे नीचे ले जाने का प्रयास करके कर सकते हैं एक लाइन तीन बार (और फिर वापस ऊपर) शुरू होने से पहले हम लाइनों को चारों ओर ले जाते हैं:jjj3k

इस प्रकार:

ggqqqqqjjj3kddjjpkddkkPjddpjj@qq@q

आप स्पष्ट रूप से रजिस्टर क्यू को स्पष्ट क्यों करते हैं? यदि आप इसे रिकॉर्ड करते हैं, तो जो कुछ भी वहां था, वह वैसे भी अधिलेखित हो जाएगा ....
वाइल्डकार्ड

4
@Wildcard क्योंकि यह एक पुनरावर्ती मैक्रो है, पहली बार जब आप रजिस्टर की सामग्री को कॉल करते हैं q, तो यह खाली होना चाहिए, अन्यथा यह आपके संस्करणों को गड़बड़ कर देगा।
सगिनॉ

बहुत अच्छा। मैं अंतःक्रियात्मक रूप से आपके आदेश के सटीक अनुक्रम को टाइप करने की कोशिश किए बिना और घाव का उपयोग करने की कोशिश करता हूं:qqqggqqjjjkddkkPjddjpkddkkPjjjj@qq@q
वाइल्डकार्ड

1
@ablewasiereisawelba where I can just use the one-line custom command each time I need to do this- ध्यान दें कि आपको मैक्रो को हर बार उपयोग करने की आवश्यकता नहीं है, क्योंकि इसे आपके vimrc पर फ़ंक्शन / कमांड के रूप में संग्रहीत करना संभव है।
mMontu

1
@ablewasiereisawelba मुझे खुशी है कि आपने "संपादन" को उपयोगी पाया! चूंकि यह आपकी पहली पोस्ट थी, शायद आप इस बात से अनभिज्ञ हों कि StackExchange सूचनाएँ कैसे काम करती हैं: जब आप एक टिप्पणी पोस्ट करते हैं, तो उत्तर / प्रश्नों के लेखक को एक सूचना मिलती है; अन्य व्यक्ति केवल तभी सूचना प्राप्त करेंगे जब आप @ <nic> को शामिल करेंगे। इस प्रकार केवल रिच आपके अंतिम संदेशों के बारे में सूचनाएँ प्राप्त करता है।
mMontu

7

आप बाहरी फ़िल्टर के रूप में Exकमांड के साथ भी ऐसा कर सकते हैं sed:

:%!sed -n 'h;n;G;h;n;G;h;n;G;p'

यह संस्करण 4 के कई से परे किसी भी अतिरिक्त लाइनों को अनदेखा (हटाएगा) 4 लाइनों से कम के अंतिम सेट (उलट) का उपयोग करने के लिए:

:%!sed -n '$p;h;n;G;$p;h;n;G;$p;h;n;G;p'

%यहाँ 'बफर में हर लाइन मतलब है। "

!आदेश का अर्थ है "इनपुट के रूप में निर्दिष्ट लाइनों के साथ निम्न आदेश चलाएँ, और की जगह आदेश के उत्पादन के साथ निर्दिष्ट लाइनों।" (इसे एक फ़िल्टर कहा जाता है, जैसे छँटाई के लिए बहुत आसान है, जैसे, :%!sortआपकी फ़ाइल में सभी पंक्तियों :2,8!sortको सॉर्ट करेगा ; लाइनों को 2-8, आदि सॉर्ट करेगा)

sedहै धारा संपादक उपकरण और सभी यूनिक्स सिस्टम पर पाया जाता है। sedयहां उपयोग की जाने वाली प्रमुख अवधारणाएं "पैटर्न स्पेस" हैं (जो डिफ़ॉल्ट रूप से बदले में इनपुट की प्रत्येक पंक्ति में शामिल हैं), और "होल्ड स्पेस" (जो कि जहां आप अतिरिक्त टेक्स्ट को छड़ी कर सकते हैं, जबकि sedइसे दूसरे को संसाधित करते समय सहेज सकते हैं इनपुट की लाइनें)।

-nsedपैटर्न स्पेस को प्रिंट करने की अपनी डिफ़ॉल्ट क्रियाओं को दबाने के लिए कमांड का एक विकल्प है (क्योंकि इस मामले में हम केवल तब प्रिंट करना चाहते हैं जब हम स्पष्ट रूप से ऐसा कहते हैं।)

$pमें sedआदेश का अर्थ है "आप की अंतिम पंक्ति पर कर रहे हैं sedके इनपुट, प्रिंट (पैटर्न अंतरिक्ष)।"

h का अर्थ है "जो कुछ भी वहाँ है, उसे अधिलेखित कर 'होल्ड स्पेस' में 'पैटर्न स्पेस' की वर्तमान सामग्री को चिपकाएँ।"

n का अर्थ है "इनपुट से अगली पंक्ति के साथ 'पैटर्न स्पेस' की सामग्री को बदलें।"

G का अर्थ है "पैटर्न स्पेस के लिए अपील": 'होल्ड स्पेस' की सामग्री के बाद एक नई रूपरेखा। "

सभी को एक साथ लिया गया, sedकमांड आउटपुट की चार पंक्तियों को स्टोर करता है, उन्हें उलट देता है क्योंकि यह उन्हें स्टोर करता है, और फिर उन्हें प्रिंट करता है। $pआदेशों दूसरे संस्करण में जोड़ा सुनिश्चित करना है कि अगर फ़ाइल की अंतिम पंक्ति 4 लाइनों की एक बहु पर के अलावा अन्य पहुँच जाता है, लाइनों अभी भी मुद्रित कर रहे हैं।


किसी वैकल्पिक-विशिष्ट सुविधाओं का उपयोग किए बिना और बाहरी फ़िल्टर का उपयोग किए बिना एक वैकल्पिक, इंटरैक्टिव दृष्टिकोण के लिए अभी भी:

:4

चौथी पंक्ति में जाने के लिए।

:.m -4 | +3m . | +2m . | +5

पिछली चार लाइनों (1-4) को उलटने के लिए और लाइन 8 पर अपने कर्सर को छोड़ दें।

.m -4लाइन चार लाइनों के पीछे (स्थानांतरित रेखा पर कर्सर को छोड़कर) के बाद बस वर्तमान लाइन को स्थानांतरित करता है।

+3m .वर्तमान रेखा के बाद 3 रेखाएँ हैं , जो वर्तमान रेखा के ठीक बाद, स्थानांतरित रेखा पर कर्सर छोड़ती है। +2m .बेशक एक ही काम करता है।

+5 कर्सर को पांच पंक्तियों के नीचे रखता है जहाँ से यह है।

इच्छानुसार दोहराएं।

विम में आप इस पूरे कमांड को दोहरा सकते हैं @:, फिर साथ दोहरा सकते हैं @@। POSIX में viया exआपको पाठ की एक पंक्ति के रूप में सम्मिलित करने की आवश्यकता होगी :.m -4 | +3m . | +2m . | +5, इसे एक नामित बफर (रजिस्टर) को हटा दें, और फिर उस नामित बफर (रजिस्टर) को निष्पादित करें।

इसलिए exमोड में, POSIX- निर्दिष्ट सुविधाओं का उपयोग करके अंतःक्रियात्मक रूप से लाइनों को उल्टा करना, और पाठ की 17 पंक्तियों के साथ शुरू करना:

Entering Ex mode.  Type "visual" to go to Normal mode.
:0a     # Append following text after "line 0" (i.e. insert at start of file).
.m -4 | +3m . | +2m . | +5
.       # End text insertion
:d k    # Delete that line to register k
line1   # This is a printout of the current line
:4      # Move to line 4
line4
:@k     # Execute register k to reverse lines 1-4
line8
:@@     # Execute register k again
line12
:@@     # Execute register k again
line16
:@@     # Execute register k again
line17
:%p     # Print the whole buffer (just to see what was done)
line4
line3
line2
line1
line8
line7
line6
line5
line12
line11
line10
line9
line16
line15
line14
line13
line17
:wq     # Save and quit

आगे की पढाई:


क्या आप थोड़ा और अपना समाधान बता सकते हैं?
वापोलिनारियो 12

3
@vappolinario, मैंने कुछ और स्पष्टीकरण जोड़ा। क्या उससे मदद हुई? :)
वाइल्डकार्ड

वाह, बहुत लंबा जवाब। :) मेरे पास sed है, वास्तव में, लेकिन मैंने इसे सिर्फ एक सरल स्क्रिप्ट के साथ उपयोग किया है जो मुझे कहीं और मिला - शायद इस बोर्ड पर - जो कि मेरे पास एक समस्या का समाधान था। हालाँकि, जब मैंने आपकी सुझाई गई लाइन को चलाने की कोशिश की, तो यह कहता है कि "'sed' को आंतरिक या बाहरी कमांड, ऑपरेशनल प्रोग्राम या बैच फ़ाइल के रूप में मान्यता नहीं मिली है।" मुझे यकीन नहीं है कि अगर मुझे विम फ़ोल्डर या क्या में sed करने की आवश्यकता है।
सक्षमवासी

1
@ablewasiereisawelba, यदि आप एक Windows बॉक्स पर चल रहे हैं और Cygwin (या MobaXterm या समान) का उपयोग नहीं कर रहे हैं, तो आप मेरे द्वारा दी गई दूसरी विधि आज़मा सकते हैं: 4G:.m -4 | +3m . | +2m . | +5<Enter>@:तब @@तक दोहराया जाए जब तक कि आपकी फ़ाइल पूरी तरह से संसाधित न हो जाए। मैं MobaXterm स्थापित करने की सलाह देता हूं, हालांकि। :)
वाइल्डकार्ड

@Wildcard ओह ठीक है, मैं अब MobaXterm की जाँच कर रहा हूँ। :)
सक्षमवाशीसेवाबा

7
:g/^/exe 'm .-' . substitute(line('.') % 4, '^0$', '4', '')

सादा अंग्रेजी: प्रत्येक पंक्ति के लिए, वर्तमान रेखा को ऊपर ले जाएं lnum % 4, जब तक कि lnum % 4 == 0किस स्थिति में वर्तमान रेखा ऊपर नहीं जाती है 4

इसके अलावा, हर nपंक्तियों को उल्टा करने के 4लिए उपरोक्त कमांड में बदलें n


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