Https://vi.stackexchange.com/a/818/227 এ থাকা উত্তরের মতো , আপনি গ্লোবাল কমান্ড ব্যবহার করতে পারেন।
এটির সাহায্যে আপনি ভিমকে কোনও প্যাটার্নের সাথে মিলিত লাইনগুলি অনুসন্ধান করতে নির্দেশ দিতে পারেন এবং তারপরে এটিতে আদেশগুলি সম্পাদন করতে পারেন।
আপনার ক্ষেত্রে, আপনি "লেভেল এন:" দিয়ে শুরু হওয়া লাইনে পাঠ্যটি প্রিপেন্ড করতে চান, যাতে আমাদের বিশ্বব্যাপী আদেশটি হতে পারে
: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
দ্বিতীয় বার ইত্যাদি দেয় This
নোট যে আমি ঘ পর কোন space করা: "%02d "
। আপনি প্রশ্নটিতে এটি জিজ্ঞাসা করেননি (এবং আমি উদাহরণ আউটপুট দেখতে পাইনি) তবে আমি সন্দেহ করেছি যে আপনি "স্তর" শব্দটি থেকে সংখ্যাটি আলাদা করতে চেয়েছিলেন। লেভেলের এল এর ঠিক পাশেই numberোকানো নম্বর পেতে প্রিন্টফকে দেওয়া স্ট্রিং থেকে স্থানটি সরান।
অবশেষে, let i = i + 1
প্রতিটি প্রতিস্থাপনের পরে এটি আমাদের কাউন্টারকে বাড়িয়ে তোলে।
এটি সাধারণভাবে কার্যকরী ডেটা সহ অন্যান্য মানদণ্ডের সাথে মিলে যাওয়া লাইনের অংশগুলি প্রতিস্থাপনের জন্য সাধারণত প্রয়োগ করা যেতে পারে।
সম্মিলিত সাধারণ কমান্ড ব্যবহার করে
সাধারণ সন্নিবেশ বা জটিল সম্পাদনার জন্য এটি ভাল। বিকল্পের মতো, আমরা গ্লোবালটি মিলাতে ব্যবহার করব, তবে নিয়মিত অভিব্যক্তি প্রতিস্থাপনের পরিবর্তে আমরা ধারাবাহিক ক্রিয়াকলাপ সম্পাদন করব যেমনটি ব্যবহারকারীর দ্বারা টাইপ করা হয়েছে।
আপনার প্রশ্নের উদাহরণ
:let i = 1 | g/^Level \d:/execute "normal! I" . printf("%02d ", i) | let i = i+1
কিভাবে এটা কাজ করে
ব্যবহৃত মানগুলি বিকল্পের সাথে খুব সমান (আমরা এখনও আমাদের সংখ্যাটি ২ টি সংখ্যার সাথে প্যাড করে 0 করার জন্য প্রিন্টফ ব্যবহার করছি) তবে অপারেশনটি ভিন্ন।
এখানে আমরা এক্সিকিউট কমান্ডটি ব্যবহার করি যা একটি স্ট্রিং নেয় এবং একটি প্রাক্তন কমান্ড ( :help :exe
) হিসাবে স্ট্রিং চালায় । আমরা একটি স্ট্রিং তৈরি করি যা আমাদের তথ্যগুলির সাথে "স্বাভাবিক! আমি" একত্রিত করে যা প্রথমবার "স্বাভাবিক! I01" এবং দ্বিতীয়বার "স্বাভাবিক! I02" ইত্যাদি হবে etc.
normal
কমান্ড সঞ্চালিত অপারেশন যেমন স্বাভাবিক মোডে পারেন। এই উদাহরণে, আমাদের সাধারণ কমান্ডটি I
, যা লাইনের শুরুতে সন্নিবেশ করে। আমরা যদি dd
এটি ব্যবহার করতাম তবে লাইনটি মুছে ফেলা o
হত, মিলিত লাইনের পরে একটি নতুন লাইন খুলবে। দেখে মনে হচ্ছে আপনি I
নিজেকে স্বাভাবিক মোডে টাইপ করেছেন (বা অন্য কোনও ক্রিয়াকলাপ)। আমরা ব্যবহার !
পর normal
নিশ্চিত কোন ম্যাপিং আমাদের পথ পেতে হবে। দেখুন :help :normal
।
তারপরে যা প্রবেশ করা হয় তা হ'ল আমাদের প্রিন্টফের মান, বিকল্প ব্যবহারের প্রথম উদাহরণ হিসাবে।
এই পদ্ধতিটি রেজেক্সের চেয়ে কল্পিত হতে পারে, কারণ আপনি এমন কিছু করতে পারেন execute "normal! ^2wy" . i . "th$p"
যা পাঠ্যের শুরুতে যাবে, ^
2 টি শব্দ এগিয়ে যাবে 2w
, ইঙ্ক 'এইচ' অক্ষর না হওয়া পর্যন্ত y" . i . "th
লাইন শেষ করবে $
এবং পেস্ট করবে p
।
এটি প্রায় কোনও ম্যাক্রো চালানোর মতো, তবে বাস্তবে কোনও রেজিস্টার ব্যবহার করে না এবং কোনও এক্সপ্রেশন থেকে স্ট্রিংগুলি একত্রিত করতে পারে। আমি এটি খুব শক্তিশালী বলে মনে করি।
প্রতিটি স্তরের নিজস্ব কাউন্টার রয়েছে এমন পদ্ধতির কাছে যান
আপনি প্রতিটি স্তরের নিজস্ব কাউন্টার পেতে চান। আপনি যদি সময়ের আগে সর্বাধিক সংখ্যা জানেন তবে আপনি নিম্নলিখিতটি করতে পারেন (সবচেয়ে বড় স্তর খুঁজে পেতে অতিরিক্ত কোড যুক্ত করা খুব কঠিন নাও হতে পারে তবে এই উত্তরটি খুব দীর্ঘ করে দেবে This এটি যত দীর্ঘ হয়)।
প্রথমে, আমি মুক্ত করতে দিই, যদি আমরা ইতিমধ্যে এটি পূর্ণসংখ্যা হিসাবে ব্যবহার করি। আমি আমি একটি তালিকায় রূপান্তর করতে পারি না, আমাদের সেভাবে তৈরি করতে হবে।
: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