ভিমে একাধিক লাইন (দুটি ব্লক) মার্জ করুন


323

আমি ভিমে দুটি ব্লক লাইন একীভূত করতে চাই, অর্থাত লাইনগুলি নিয়ে n..mএবং সেগুলিকে লাইনে যুক্ত করতে চাই a..b। আপনি যদি সিডোকোড ব্যাখ্যা পছন্দ করেন:[a[i] + b[i] for i in min(len(a), len(b))]

উদাহরণ:

abc
def
...

123
45
...

হয়ে উঠতে হবে

abc123
def45

ম্যানুয়ালি অনুলিপি এবং পেস্ট না করে এটি করার কোনও দুর্দান্ত উপায় আছে কি?


সুতরাং ... আপনি বিকল্প লাইনে যোগদান করতে চান? অর্থাৎ আপনি লাইন যোগ দিতে চান xযোগদানের সঙ্গে x+2?

1
না, আমার দুটি পৃথক ব্লক আছে। সিউডোকোড-ইশ:[a[i] + b[i] for i in min(len(a), len(b))]
থিফমাস্টার 25'12

2
একটি অনুরূপ প্রশ্ন (এবং উত্তর!) দেখুন এখানে
NWS

উত্তর:


880

আপনি অবশ্যই একটি একক অনুলিপি / পেস্ট (ব্লক-মোড নির্বাচন ব্যবহার করে) দিয়ে এটি করতে পারেন, তবে আমি অনুমান করছি যে এটি আপনি চান না।

আপনি যদি এটি করতে চান তবে প্রাক্তন কমান্ডগুলি

:5,8del | let l=split(@") | 1,4s/$/\=remove(l,0)/

রূপান্তরিত হবে

work it 
make it 
do it 
makes us 
harder
better
faster
stronger
~

মধ্যে

work it harder
make it better
do it faster
makes us stronger
~

আপডেট: এটির অনেকগুলি উত্তর নিয়ে উত্তর আরও বিশদ ব্যাখ্যার দাবি রাখে।

ভিমে, আপনি |একাধিক প্রাক্তন কমান্ড চেইন করতে পাইপ অক্ষর ( ) ব্যবহার করতে পারেন, সুতরাং উপরেরটি সমান

:5,8del
:let l=split(@")
:1,4s/$/\=remove(l,0)/

অনেক Ex কমান্ড একটি উপসর্গ আর্গুমেন্ট হিসাবে লাইনের একটি সীমার গ্রহণ করা - এসব উপরে ক্ষেত্রে 5,8সামনে delএবং 1,4পূর্বে s///নির্দিষ্ট করে লাইন কমান্ড উপর কাজ করে।

delপ্রদত্ত লাইনগুলি মুছে দেয়। এটি একটি রেজিস্টার আর্গুমেন্ট নিতে পারে, কিন্তু যখন একটি দেওয়া না হয়, এটি নামবিহীন রেজিস্টারে লাইনগুলি ডাম্প করে দেয় @", ঠিক যেমনটি মোডে মোছার মতো করে। let l=split(@")তারপরে মুছে ফেলা লাইনগুলি ডিফল্ট ডিলিমিটার: হোয়াইটস্পেস ব্যবহার করে একটি তালিকায় বিভক্ত করে। মোছা রেখাগুলিতে সাদা জায়গার ইনপুটটিতে সঠিকভাবে কাজ করতে, যেমন:

more than 
hour 
our 
never 
ever
after
work is
over
~

আমরা প্রতিরোধ, একটি ভিন্ন বিভেদক নির্দিষ্ট করতে হবে চাই দুই তালিকা উপাদানের মধ্যে বিভক্ত হওয়া থেকে "কাজ নেই": let l=split(@","\n")

পরিশেষে, প্রতিস্থাপনে s/$/\=remove(l,0)/, আমরা প্রতিটি লাইনের শেষটিকে ( $) এর প্রকাশের মান দিয়ে প্রতিস্থাপন করি remove(l,0)remove(l,0)তালিকাটি পরিবর্তন করে l, মুছে ফেলা এবং এর প্রথম উপাদানটি ফিরে আসে। এটি আমাদের মুছে ফেলা লাইনগুলিকে ক্রমটি প্রতিস্থাপন করতে দেয়। আমরা পরিবর্তে মুছে ফেলা লাইনগুলি ব্যবহার করে বিপরীত ক্রমে প্রতিস্থাপন করতে পারি remove(l,-1)


1
হুম ... আমাকে কেবল একবার এন্টার টিপতে হবে। এবং এটি দুটি অংশের মধ্যে কোনও স্থান সন্নিবেশ করবে না। যদি লাইনে কিছু পেছনের জায়গা থাকে (যেমন "এটি কাজ করুন" উদাহরণস্বরূপ), এখনও থাকবে। আপনি এর s/\s*$/পরিবর্তে যেকোন ট্রেলিং স্পেস থেকে মুক্তি পেতে পারেন s/$/
রাম্পিয়ান

1
ব্যাখ্যার জন্য ধন্যবাদ. :sil5,8del | let l=split(@") | sil1,4s/$/\=remove(l,0)/ | call histdel("/", -1) | nohlsএটি আরও ভাল বলে মনে হচ্ছে যেহেতু এটি চলার পরে অনুসন্ধানের ইতিহাস পরিষ্কার করে। এবং এটি "এক্স আরও / কম লাইন" বার্তাটি দেখায় না যাতে আমাকে এন্টার টিপতে হবে।
চোরমাস্টার

11
আপনি যে উত্তরের জন্য পূর্ণ তেজ রেফারেন্স চাইলে: :help range, :help :d, :help :let, :help split(), :help :s, :help :s\=, :help remove()
বেনোইট

16
আপনার মতো লোকেরা উত্তরগুলি পোস্ট করতে চান তা নিশ্চিত করেই আমি মডারেটর হয়েছি। শুভ শো :)
টিম পোস্ট

1
প্রথম 4 টি বাক্য পরে কোনও সাদা স্থান না থাকলে সমস্যা আছে।
রেমন

58

সমস্যা সমাধানে কোনো সুরুচিপূর্ণ এবং সংক্ষিপ্ত প্রাক্তন কমান্ড মিশ্রন পাওয়া যেতে পারে :global, :moveএবং :joinকমান্ড। ধরে নিলাম যে লাইনের প্রথম ব্লকটি বাফারের প্রথম লাইনে শুরু হয় এবং কার্সারটি দ্বিতীয় ব্লকের প্রথম লাইনের পূর্ববর্তী লাইনে অবস্থিত, নিম্নরূপ কমান্ডটি রয়েছে।

:1,g/^/''+m.|-j!

এই কৌশলটির বিশদ ব্যাখ্যার জন্য, আমার অনুরূপ প্রশ্নের উত্তরটি দেখুন " ভিম পেস্ট-ডি '' আচরণটি বক্সের বাইরে রয়েছে? "।


E16: Invalid Range- তবে এটি যাইহোক কাজ করে। অপসারণ করার সময় 1,এটি ত্রুটি ছাড়াই কাজ করে।
চোরমাস্টার

এবং খুব খারাপ আপনি একাধিক উত্তর গ্রহণ করতে পারবেন না - অন্যথায় আপনারও সবুজ চিহ্ন রয়েছে!
চোরমাস্টার

3
খুব সুন্দর! আমি :moveএবং সম্পর্কে জানতাম না :join!, বা ''একটি ব্যাপ্তি যুক্তি হিসাবে কী বোঝায় ( :help '') এবং কী +এবং -ব্যাপ্তি সংশোধক ( :help range) হিসাবে কী বোঝায় । ধন্যবাদ!
রামপিন

@ থিফমাস্টার: কমান্ডটি যখন যুক্ত হওয়ার জন্য দুটি রেঞ্জের রেখা একে অপরের সাথে সংলগ্ন হয় তখন ব্যবহার করার জন্য ডিজাইন করা হয়েছিল, যাতে কার্সারটি প্রথম ব্লকের প্রথম লাইনের সাথে সাথে প্রথম ব্লকের অবিলম্বে উপস্থিত হয়। (লিঙ্কিত উত্তর এবং প্রশ্ন দেখুন।) ব্লকগুলিতে লাইন সংখ্যা পৃথক হলেও কমান্ডটি উদ্দেশ্য হিসাবে কাজ করে, যদিও এটি ক্ষেত্রে ত্রুটি বার্তা দেয়। sil!কমান্ডটি প্রিপেন্ড করে কেউ ত্রুটি বার্তাগুলি দমন করতে পারে ।
ইব।

2
@ বিঃ: আমি মনে করি এই উত্তরটিও বিস্তারিত ব্যাখ্যা করা ভাল ধারণা হবে।
চোরমাস্টার

44

অবরুদ্ধ লাইনে যোগ দিতে, আপনাকে নিম্নলিখিত পদক্ষেপগুলি করতে হবে:

  1. তৃতীয় লাইনে যান: jj
  2. ভিজ্যুয়াল ব্লক মোড প্রবেশ করুন: CTRL-v
  3. রেখার শেষে কার্সারটি অ্যাঙ্কর করুন (বিভিন্ন দৈর্ঘ্যের লাইনের জন্য গুরুত্বপূর্ণ): $
  4. শেষে যান: CTRL-END
  5. ব্লক কাটা: x
  6. প্রথম লাইনের শেষে যান: kk$
  7. ব্লকটি এখানে আটকান: p

আন্দোলনটি সেরা নয় (আমি কোনও বিশেষজ্ঞ নই), তবে এটি আপনার পছন্দ মতো কাজ করে। আশা করি এর সংক্ষিপ্ত সংস্করণ থাকবে।

এখানে পূর্বশর্তগুলি তাই এই কৌশলটি ভালভাবে কাজ করে:

  • প্রারম্ভিক ব্লকের সমস্ত লাইনের (প্রশ্নের উদাহরণে abcএবং def) একই দৈর্ঘ্যের এক্সওআর রয়েছে
  • প্রারম্ভিক ব্লকের প্রথম লাইনটি দীর্ঘতম এবং আপনি এর মধ্যে অতিরিক্ত স্পেসের বিষয়ে চিন্তা করবেন না) XOR
  • প্রারম্ভিক ব্লকের প্রথম লাইনটি দীর্ঘতম নয় এবং শেষ পর্যন্ত আপনার অতিরিক্ত স্থান রয়েছে।

ওহ, এটি আকর্ষণীয়! আমি কখনই ভাবিনি যে এটি সেভাবে কাজ করবে।
voithos

13
এটি কেবল কারণ হিসাবে চেয়েছিল abcএবং defএকই দৈর্ঘ্যের হিসাবে কাজ করে । ব্লক নির্বাচন মুছে ফেলা পাঠ্যের ইন্ডেন্টগুলি রক্ষা করবে, সুতরাং যদি পাঠ্যটি রাখার সময় কার্সারটি যদি একটি সংক্ষিপ্ত রেখায় থাকে, লম্বাগুলি লম্বাগুলির মধ্যে বর্ণগুলির মধ্যে সন্নিবেশিত হয় - এবং যদি কার্সার বেশি থাকে তবে সংক্ষিপ্তগুলিতে ফাঁকা স্থান যুক্ত হয় এক.
ইজকাটা 26'12

প্রকৃতপক্ষে ... ব্লক অনুলিপি এবং পেস্ট ব্যবহার করে এটি সঠিকভাবে করার কোনও উপায় আছে কি? সর্বোপরি এটি করার সহজতম উপায় (বিশেষত যদি আপনি এখানে কোনও কারণে আরও জটিল উপায়গুলি দেখতে না পারেন)।
চোরমাস্টার

2
@ ইজকাটা বলেছে আপনি দীর্ঘ লাইনের মাঝে পাঠ্য প্রবেশ করানোর সমস্যায় পড়বেন। এটিকে কার্যকরী করার জন্য, এটিকে দীর্ঘতম করার জন্য প্রথম লাইনের শেষে আরও স্পেস যুক্ত করুন এবং তারপরে আপনার পাঠ্যের ব্লকটি পেস্ট করুন। একবার হয়ে গেলে, একের সাথে একাধিক স্পেস সংক্ষেপণ করা সহজ:%s/ \+/ /g
খাজা মিনহাজউদ্দিন

1
set ve=allসাহায্য করা উচিত, vimdoc.sourceforge.net/htmldoc/options.html#'virtualedit '
বেন

19

এটি আমি এখানে কীভাবে করব (প্রথম লাইনে কার্সার সহ):

qama:5<CR>y$'a$p:5<CR>dd'ajq3@a

আপনার দুটি জিনিস জানা দরকার:

  • দ্বিতীয় গ্রুপের প্রথম লাইনটি যে লাইন নম্বরটি শুরু হয় (আমার ক্ষেত্রে 5) এবং
  • প্রতিটি গ্রুপে রেখার সংখ্যা (আমার উদাহরণে 3)।

যা চলছে তা এখানে:

  • qaqএকটি "বাফার" ইন পরবর্তী পর্যন্ত সবকিছু রেকর্ড করে a
  • ma বর্তমান লাইনে একটি চিহ্ন তৈরি করে।
  • :5<CR> পরের গ্রুপে যায়
  • y$ বাকী রেখায় ইয়াঙ্কস।
  • 'a চিহ্ন ফিরে, আগে সেট।
  • $p লাইনের শেষদিকে আটকান।
  • :5<CR> দ্বিতীয় গ্রুপের প্রথম লাইনে ফিরে আসে।
  • dd এটি মুছে দেয়।
  • 'a চিহ্ন ফিরে।
  • jq এক লাইন নেমে যায়, এবং রেকর্ডিং বন্ধ।
  • 3@a প্রতিটি লাইনের ক্রিয়া পুনরাবৃত্তি করে (আমার ক্ষেত্রে 3)

1
আপনি টাইপ করার [Enter]পরে :5উভয়ই টিপতে হবে অথবা এটি কাজ করবে না।
শন জে গফ

1
আমি জিভিমে আছি জিভিমে এই আদেশটি অনুলিপি করে আটকানোর কোনও উপায় আছে কি? Currently ভি আমি স্বয়ংক্রিয়ভাবে (?) মোডে থাকলেও সারণি মোডে স্বয়ংক্রিয়ভাবে আটকানো মোডে (যা বোঝায় যে লোকেরা সাধারণত যা চায়) তা আটকায়। আমি চেষ্টা করেছি :norm qama:5<CR>y$'a$p:5<CR>dd'ajq3@aতবে মনে হয় এটি কার্যকর হবে q
চোরমাস্টার

1
থিফমাস্টার: চেষ্টা করুন :let @a="ma:5^My$'a$p:5^Mdd'aj" | normal 4@a, যেখানে ^Mসিটিআরএল-ভি চাপুন তারপরে অক্ষরগুলি টাইপ করা হয়েছে।
রামপিন

8

অন্য কোথাও উল্লিখিত হিসাবে, ব্লক নির্বাচনটি হ'ল উপায়। তবে আপনি যে কোনও রূপ ব্যবহার করতে পারেন:

:!tail -n -6 % | paste -d '\0' % - | head -n 5

এই পদ্ধতিটি ইউএনআইএক্স কমান্ড লাইনের উপর নির্ভর করে। pasteউপযোগ লাইন মার্জ এই সাজানোর হ্যান্ডেল করতে তৈরি করা হয়েছে।

PASTE(1)                  BSD General Commands Manual                 PASTE(1)

NAME
     paste -- merge corresponding or subsequent lines of files

SYNOPSIS
     paste [-s] [-d list] file ...

DESCRIPTION
     The paste utility concatenates the corresponding lines of the given input files, replacing all but the last file's newline characters with a single tab character,
     and writes the resulting lines to standard output.  If end-of-file is reached on an input file while other input files still contain data, the file is treated as if
     it were an endless source of empty lines.

ব্লক নির্বাচন ব্যবহার করা একমাত্র উপায় নয়। না এটি সবচেয়ে সহজ এক। পছন্দসই ( paste -d-র মতো) আচরণটি সংক্ষিপ্ত Vim কমান্ডের মাধ্যমে প্রয়োগ করা যেতে পারে, যেমনটি আমার উত্তরে প্রদর্শিত হয়েছে ।
ইব।

3
তদ্ব্যতীত, আমি উইন্ডোতে রয়েছি যাতে সমাধানটি আমার লিনাক্স মেশিনে একটি এসএসএইচ সংযোগ খোলার সাথে এবং সম্পাদক থেকে টার্মিনাল এবং পিছনে আটকানো জড়িত।
চোরমাস্টার

3

নমুনা ডেটা রাম্পুনের মতোই।

:1,4s/$/\=getline(line('.')+4)/ | 5,8d

3

আমি এটিকে খুব জটিল করে তুলব বলে মনে করি না। আমি কেবল
( :set virtualedit=all)
নির্বাচন করুন ব্লক 123 এবং নীচে সমস্তটিতে সার্থকতা নির্ধারণ করব ।
এটি প্রথম কলামের পরে রাখুন:

abc    123
def    45
...    ...

এবং একাধিক স্পেস থেকে 1 স্পেসের মধ্যে সরিয়ে ফেলুন:

:%s/\s\{2,}/ /g

প্রশ্নটি আসলে কোনও ফাঁকা জায়গাগুলির জন্য জিজ্ঞাসা করে না, আমি এমন কিছু করব gvV:'<,'>s/\s+//g(ভিএমটি স্বয়ংক্রিয়ভাবে আপনার '<,'>জন্য সন্নিবেশ করা উচিত যাতে আপনার নিজের হাতে এটি টাইপ করার দরকার নেই)।
বেন

2

আমি জটিল পুনরাবৃত্তি ব্যবহার করব :)

প্রদত্ত এই:

aaa
bbb
ccc

AAA
BBB
CCC

প্রথম লাইনে কার্সার সহ, নিম্নলিখিত টিপুন:

qa}jdd''pkJxjq

এবং তারপরে চাপুন @a(এবং আপনি পরবর্তীকালে ব্যবহার করতে পারেন @@) যতবার প্রয়োজন ততবার।

আপনার সাথে শেষ করা উচিত:

aaaAAA
bbbBBB
cccCCC

(প্লাস একটি নিউলাইন।)

Explaination:

  • qa একটি জটিল পুনরাবৃত্তি রেকর্ডিং শুরু a

  • } পরবর্তী ফাঁকা লাইনে লাফ দেয়

  • jdd পরবর্তী লাইন মুছে ফেলা হয়

  • '' শেষ লাফ দেওয়ার আগে অবস্থানে ফিরে যায়

  • p মুছে ফেলা লাইনটি বর্তমানের নীচে আটকান

  • kJ পূর্ববর্তী একের শেষে বর্তমান লাইনটি যুক্ত করুন

  • xJসম্মিলিত লাইনের মধ্যে যুক্ত হওয়া স্থানটি মুছুন ; আপনি যদি জায়গা চান তবে এটি বাদ দিতে পারেন

  • j পরের লাইনে যান

  • q জটিল পুনরাবৃত্তি রেকর্ডিং শেষ

এর পরে আপনি @aসঞ্চিত জটিল পুনরাবৃত্তিটি চালানোর জন্য ব্যবহার করবেন aএবং তারপরে আপনি @@শেষ দৌড়ে থাকা জটিল পুনরাবৃত্তিটি পুনরায় চালাতে ব্যবহার করতে পারবেন ।


1

এটি সম্পন্ন করার জন্য অনেকগুলি উপায় থাকতে পারে। আমি নিম্নলিখিত দুটি পদ্ধতি ব্যবহার করে দুটি ব্লকের পাঠ্য একত্রীকরণ করব merge

ধরা যাক প্রথম ব্লকটি লাইন 1-এ রয়েছে এবং 2 য় ব্লকটি লাইন 10 থেকে কার্সারের প্রাথমিক অবস্থানের সাথে লাইন 10 থেকে শুরু হবে।

(\ n এর অর্থ এন্টার কী টিপুন)

1. abc
   def
   ghi        

10. 123
    456
    789

কমান্ডগুলি ব্যবহার করে ম্যাক্রো সহ: অনুলিপি করুন, পেস্ট করুন এবং যোগদান করুন।

qaqqa + 9y \ npkJjq2 @ a10G3dd

ম্যাক্রো ব্যবহার করে কমান্ডগুলি নবম লাইন নম্বরে একটি লাইন সরিয়ে নিয়ে যোগদান করে।

qcqqc: 10 মি। k nkJjq2 @ গ

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.