আমি আপনার সাথে একমত হবে - এটা সম্ভবত হয় একটি জেনেরিক সমস্যা। যদিও কিছু সাধারণ ইউটিলিটিগুলির এটি পরিচালনা করার জন্য কিছু সুবিধা রয়েছে।
nl
nlউদাহরণস্বরূপ, দুটি অক্ষরের বিভাগের ডিলিমিটার দ্বারা সরানো হিসাবে লজিক পৃষ্ঠাগুলিতে ইনপুট পৃথক করে । একটি লাইনে তিনটি ঘটনা একাই শিরোনামের সূচনা নির্দেশ করে , দুটি শরীর এবং একটি পাদচরণ । এটি ইনপুটটিতে পাওয়া এগুলির যে কোনও একটি আউটপুটে ফাঁকা রেখার সাথে প্রতিস্থাপন করে - এটি কেবলমাত্র ফাঁকা রেখা প্রিন্ট করে-d
অন্য একটি বিভাগ অন্তর্ভুক্ত করার জন্য আমি এটি আপনার উদাহরণ পরিবর্তন করেছি ./infile। সুতরাং এটির মতো দেখাচ্ছে:
line A
line B
@@inline-code-start
line X
line Y
line Z
@@inline-code-end
line C
line D
@@start
line M
line N
line O
@@end
তারপরে আমি নীচে দৌড়েছি:
sed 's/^@@.*start$/@@@@@@/
s/^@@.*end$/@@/' <infile |
nl -d@@ -ha -bn -w1
nlলজিকাল পৃষ্ঠাগুলি জুড়ে রাজ্যে একত্রিত হতে বলা যেতে পারে , তবে এটি ডিফল্টরূপে হয় না। পরিবর্তে এটি শৈলী এবং বিভাগ অনুসারে এর ইনপুটটির রেখাটি সংখ্যায়িত করবে । সুতরাং -haসমস্ত শিরোনামের লাইন সংখ্যা এবং -bnমানে কোনও বডি লাইন - যেহেতু এটি কোনও শরীরের অবস্থায় শুরু হয় ।
যতক্ষণ না আমি এটি শিখেছি আমি nlকোনও ইনপুট ব্যবহার করতাম , তবে বুঝতে পারার পরে যে nlএটির ডিফল্ট -dএলিমিটার অনুসারে আউটপুটটি বিকৃত হতে পারে \:আমি এর সাথে আরও সতর্কতা অবলম্বন করতে শিখেছি এবং grep -nF ''পরিবর্তে অনির্ধারিত ইনপুট ব্যবহার করতে শুরু করেছি । তবে সেই দিনটি শিখানো আরেকটি শিক্ষাটি ছিল যে nlএটি অন্যান্য ক্ষেত্রে যেমন খুব কার্যকরভাবে প্রয়োগ করা যেতে পারে - যেমন এই - আপনি যদি কেবল তার ইনপুটটিকে কিছুটা সংশোধন করেন - যেমন আমি sedউপরের সাথে করি ।
আউটপুট
line A
line B
1 line X
2 line Y
3 line Z
line C
line D
1 line M
2 line N
3 line O
এখানে আরও কিছু nl- আপনি উপরে লক্ষ করেছেন কীভাবে সমস্ত রেখাগুলি বাদে শূন্যস্থান দিয়ে শুরু হয়? nlসংখ্যার রেখাগুলি যখন এটি প্রতিটিের মাথার মধ্যে একটি নির্দিষ্ট সংখ্যক অক্ষর সন্নিবেশ করে। এই রেখাগুলির জন্য এটি সংখ্যা নয় - শূন্যস্থানগুলিও - এটি সর্বদা -wশনাক্তকরণহীন -sলাইনের শীর্ষে ফাঁকা স্থানগুলি ( আইডথ গণনা + ইপারেটর লেন) সন্নিবেশ করে ইন্ডেন্টের সাথে মেলে । এটি আপনাকে সংখ্যাযুক্ত বিষয়বস্তুটির সাথে সংখ্যার বিষয়বস্তুর সাথে তুলনা করে - এবং অল্প প্রচেষ্টা দিয়ে পুনরুত্পাদন করতে দেয়। যখন আপনি বিবেচনা করেন যে nlএটির জন্য আপনার ইনপুটটি যৌক্তিক বিভাগগুলিতে বিভক্ত করবে এবং আপনি -sপ্রতিটি লাইনটির শীর্ষে নির্বিচারে ট্র্যাংগুলি সন্নিবেশ করতে পারেন , তার আউটপুটটি পরিচালনা করা খুব সহজ হয়ে যায়:
sed 's/^@@.*start$/@@@@@@/
s/^@@.*end/@@/; t
s/^\(@@\)\{1,3\}$/& /' <infile |
nl -d@@ -ha -bn -s' do something with the next line!
'
উপরের প্রিন্টগুলি ...
line A
line B
1 do something with the next line!
line X
2 do something with the next line!
line Y
3 do something with the next line!
line Z
line C
line D
1 do something with the next line!
line M
2 do something with the next line!
line N
3 do something with the next line!
line O
গনুহ sed
যদি nlআপনার টার্গেট আবেদন নয়, তারপর একটি গনুহ sedকরতে eআপনি একটি ম্যাচ উপর নির্ভর করে একটি অবাধ শেল কমান্ড xecute।
sed '/^@@.*start$/!b
s//nl <<\\@@/;:l;N
s/\(\n@@\)[^\n]*end$/\1/
Tl;e' <infile
উপরের sedপ্যাটার্ন স্পেসে ইনপুট সংগ্রহ করে যতক্ষণ না এটি সফলভাবে প্রতিস্থাপনের পাসটি পাস করতে Tএবং আবেলের bপিছনে :lপাল্লা দেওয়া বন্ধ করে দেয় । এটি যখন হয়ে যায়, এটি এর eবাকী সমস্ত প্যাটার্ন-স্পেসের জন্য এখানে-নথি nlহিসাবে উপস্থাপিত হয়ে ইনপুট দিয়ে xecutes করে <<।
কর্মপ্রবাহ এইরকম:
/^@@.*start$/!b
- যদি কোনো
^সমগ্র লাইন $নেই !না /মেলে /উপরে প্যাটার্ন, তাহলে এটি করা হয় bস্ক্রিপ্টের বাইরে ranched এবং autoprinted - তাই এই বিন্দু থেকে আমরা কেবল যা প্যাটার্ন সঙ্গে শুরু লাইনের সিরিজের সঙ্গে কাজ করছে।
s//nl <<\\@@/
- খালি
s//ক্ষেত্রটি /শেষের ঠিকানাটির sedসাথে মিলের চেষ্টা করার জন্য দাঁড়িয়েছে - সুতরাং এই কমান্ডটি পরিবর্তে পুরো @@.*startলাইনটিকে প্রতিস্থাপন করবে nl <<\\@@।
:l;N
:কমান্ড একটি শাখা ট্যাগ সংজ্ঞায়িত - এখানে আমি এক নামে সেট :lআবেল। NEXT কমান্ড পাশে একটি দ্বারা অনুসরণ প্যাটার্ন স্থান ইনপুট লাইন appends \newline অক্ষর। \nকোনও sedপ্যাটার্ন স্পেসে ই- লাইন পাওয়ার কয়েকটি উপায়গুলির মধ্যে এটি - \nইওলাইন চরিত্রটি কোনও ডেরের কাছে নিশ্চিতভাবে ডিলিমিটার, sedযিনি এটি কিছুক্ষণ করছেন।
s/\(\n@@\)[^\n]*end$/\1/
- এই
s///প্রতিবন্ধকতা কেবলমাত্র কোনও শুরুর মুখোমুখি হওয়ার পরে এবং শুধুমাত্র শেষের লাইনের প্রথম নিম্নলিখিত ইভেন্টে সফল হতে পারে । এটি কেবলমাত্র একটি প্যাটার্ন স্পেসে কাজ করবে যেখানে প্যাটার্ন স্পেসের একেবারে শেষ চিহ্নিত করে \nঅবিলম্বে চূড়ান্ত ewline অনুসরণ করা হবে। যখন এটি কাজ করে, এটা দিয়ে পুরো মিলেছে স্ট্রিং প্রতিস্থাপন প্রথম গ্রুপ , বা ।@@.*end$\1\(\)\n@@
Tl
Tকোন লেবেলে হল কমান্ড শাখা (যদি প্রদত্ত) যদি একটি সফল প্রতিস্থাপন শেষ সময় একটি ইনপুট লাইন প্যাটার্ন মহাকাশ টানা ছিল যেহেতু ঘটেছে করেনি (আমি W / কি হিসাবে N) । এর অর্থ হ'ল প্রতিবারের মতো \newline প্যাটার্ন স্পেসে যুক্ত হবে যা আপনার শেষ ডিলিমিটারের সাথে মেলে না, Tইস্ট কমান্ড ব্যর্থ হয় এবং শাখাগুলি :lহাবলে ফিরে যায় , যার ফলশ্রুতি এক্সট লাইনটি sedটানতে এবং Nসফল হওয়া পর্যন্ত লুপ করে।
e
যখন শেষ ম্যাচের বিকল্পটি সফল হয় এবং স্ক্রিপ্টটি কোনও ব্যর্থ স্থানে ফিরে আসে না T, তখন sedএই eআদেশটি xecute করবে l:
nl <<\\@@\nline X\nline Y\nline Z\n@@$
দেখতে দেখতে শেষ লাইনটি সম্পাদনা করে আপনি নিজের জন্য এটি দেখতে পারেন Tl;l;e ।
এটি প্রিন্ট করে:
line A
line B
1 line X
2 line Y
3 line Z
line C
line D
1 line M
2 line N
3 line O
while ... read
এটি করার একটি শেষ উপায় এবং সম্ভবত সবচেয়ে সহজ উপায় হ'ল while readলুপ ব্যবহার করা , তবে সঙ্গত কারণে। শেলটি - (বিশেষত একটি bashশেল) - সাধারণত প্রচুর পরিমাণে বা অবিচলিত স্ট্রিমগুলিতে ইনপুট পরিচালনা করার ক্ষেত্রে বেশ অদ্ভুত। এটিও বোধগম্য হয় - শেলের কাজ হ'ল অক্ষর অনুসারে ইনপুট চরিত্রটি পরিচালনা করা এবং বড় কমান্ডগুলি পরিচালনা করতে পারে এমন অন্যান্য কমান্ড কল করা।
কিন্তু গুরুত্বপূর্ণ হল তার ভূমিকা সম্পর্কে নেই শেল না read ইনপুটের অতিরিক্ত - এটি নির্দিষ্ট করা না পয়েন্ট যে এটা এত হ্রাস বা সময় যথেষ্ট রিলে এই নয় যে কমান্ড এটা কল ফেলে রাখা হয় উদাসীন ইনপুট অথবা আউটপুট বাফার - বাইট সুতরাং ইনপুট বাকী আছে কি না এবং আপনার এটি পড়ার জন্য পরবর্তী কমান্ডটি কল করা উচিত - এই তথ্যের readজন্য একটি দুর্দান্ত ইনপুট পরীক্ষার ব্যবস্থা করেreturn তবে এটি অন্যথায় যাবার সেরা উপায় নয়।
সিঙ্ক ইনপুট প্রক্রিয়াজাতকরণের জন্য কেউ কীভাবে read এবং অন্যান্য আদেশ ব্যবহার করতে পারে তার উদাহরণ এখানে রয়েছে :
while IFS= read -r line &&
case $line in (@@*start) :;; (*)
printf %s\\n "$line"
sed -un "/^@@.*start$/q;p";;
esac;do sed -un "/^@@.*end$/q;=;p" |
paste -d: - -
done <infile
প্রতিটি পুনরাবৃত্তির জন্য প্রথম যেটি ঘটে তা হ'ল readএকটি লাইনে টান। যদি এটি সফল হয় তবে এর অর্থ লুপটি এখনও ইওএফ-তে আঘাত করে নি এবং তাই caseএটির সাথে একটি শুরু ডিলিমিটারের সাথে মেলে doব্লকটি তত্ক্ষণাত কার্যকর করা হয় exec অন্যথায়, এটি printfমুদ্রণ এবং বলা হয়।$linereadsed
sedহবে pনা হওয়া পর্যন্ত encounters যে লাইন দ্রণ শুরু যখন এটি - মার্কার qসম্পূর্ণভাবে ইনপুট uits। -uNbuffered সুইচ গনুহ জন্য প্রয়োজনীয় sedকারণ এটি বরং সাগ্রহে অন্যথায় বাফার করতে পারেন, কিন্তু - বৈশিষ্ট অনুযায়ী - অন্য POSIX sedগুলি কোনো বিশেষ বিবেচনা ছাড়া কাজ করা উচিত - তাই যতদিন <infileএকটি নিয়মিত ফাইল।
যখন প্রথম sed qইউটিস হয়, শেলটি লুপটির doব্লকটি সম্পাদন করে - যা অন্যটিকে কল করে sedযা প্রতিটি লাইন প্রান্তিক না হওয়া পর্যন্ত শেষ করে । এটি তার আউটপুটটি পাইপ করে paste, কারণ এটি প্রতিটি নিজস্ব লাইনে লাইন নম্বর প্রিন্ট করে। এটার মত:
1
line M
2
line N
3
line O
pasteতারপরে :অক্ষরগুলিতে এগুলি একত্রিত করে এবং পুরো আউটপুটটি দেখতে দেখতে:
line A
line B
1:line X
2:line Y
3:line Z
line C
line D
1:line M
2:line N
3:line O
এগুলি কেবল উদাহরণস্বরূপ - পরীক্ষায় বা ব্লকগুলিতে যে কোনও কিছুই করা যেতে পারে, তবে প্রথম ইউটিলিটি অবশ্যই খুব বেশি ইনপুট গ্রহণ করবে না।
জড়িত সমস্ত ইউটিলিটি একই ইনপুট পড়ুন - এবং ফলাফলগুলি মুদ্রণ করুন - প্রত্যেকে নিজের পরিবর্তে। জিনিস এই ধরনের আসে পেতে কঠিন হতে পারে - কারণ বিভিন্ন ইউটিলিটি অন্যদের তুলনায় বেশি বাফার হবে - কিন্তু আপনি সাধারণত নির্ভর করতে পারেন dd, headএবং sedডান জিনিস করতে (যদিও, গনুহ জন্য sed, আপনি CLI-সুইচ প্রয়োজন) এবং আপনার সর্বদা নির্ভর করতে সক্ষম হওয়া উচিত read- কারণ এটি প্রকৃতির দ্বারা খুব ধীর । এবং এই কারণেই উপরের লুপটি প্রতি ইনপুট ব্লকটিকে কেবল একবারে কল করে।
nlরাষ্ট্র জমে আছে না । লুক এnl -dএবং আপনার চেকেman/infoতথ্যের জন্য পৃষ্ঠাগুলিnl'র অধ্যায় বিভেদক ।