কোনও ধরণে একটি বৃহত ফাইলকে কীভাবে দুটি ভাগে ভাগ করবেন?
একটি উদাহরণ দেওয়া file.txt
:
ABC
EFG
XYZ
HIJ
KNL
আমি এই ফাইলটি XYZ
এমনভাবে বিভক্ত করতে চাই যাতে file1
লাইন আপ-টু XYZ
এবং বাকী রেখাগুলি থাকে file2
।
কোনও ধরণে একটি বৃহত ফাইলকে কীভাবে দুটি ভাগে ভাগ করবেন?
একটি উদাহরণ দেওয়া file.txt
:
ABC
EFG
XYZ
HIJ
KNL
আমি এই ফাইলটি XYZ
এমনভাবে বিভক্ত করতে চাই যাতে file1
লাইন আপ-টু XYZ
এবং বাকী রেখাগুলি থাকে file2
।
উত্তর:
আপনি যা awk
করতে পারেন তা সহ:
awk '{print >out}; /XYZ/{out="file2"}' out=file1 largefile
ব্যাখ্যা: প্রথম awk
আর্গুমেন্ট ( out=file1
) ফাইলনামের সাথে একটি ভেরিয়েবল সংজ্ঞা দেয় যা পরবর্তী আর্গুমেন্ট ( largefile
) প্রক্রিয়া করার সময় আউটপুট জন্য ব্যবহৃত হবে । awk
প্রোগ্রাম পরিবর্তনশীল দ্বারা নির্দিষ্ট ফাইলে সব লাইন প্রিন্ট হবে out
( {print >out}
)। যদি প্যাটার্নটি XYZ
পাওয়া যায় তবে আউটপুট ভেরিয়েবলটি নতুন ফাইল ( {out="file2}"
) -এ চিহ্নিত করতে পুনরায় সংজ্ঞায়িত করা হবে যা পরবর্তী ডেটা লাইনগুলি মুদ্রণের জন্য লক্ষ্য হিসাবে ব্যবহৃত হবে।
তথ্যসূত্র:
এটি একটি কাজ csplit
:
csplit -sf file -n 1 large_file /XYZ/
হবে s
ilently ফাইল বিভক্ত, প্রাক দিয়ে তোমাকে টুকরা টুকরা তৈরি f
IX file
এবং n
একটি একক অঙ্ক ব্যবহার umbered যেমন file0
ইত্যাদি লক্ষ্য করুন ব্যবহার /regex/
করার জন্য বিভক্ত হবে, কিন্তু যে ম্যাচ লাইন সহ না regex
। আপ বিভক্ত করতে এবং লাইন ম্যাচিং সহ regex
যোগ একটি +1
অফসেট:
csplit -sf file -n 1 large_file /XYZ/+1
এটি দুটি ফাইল তৈরি করে file0
এবং file1
। আপনার যদি তাদের নামকরণের প্রয়োজন হয় file1
এবং file2
আপনি সর্বদা csplit
কমান্ডটিতে একটি খালি প্যাটার্ন যুক্ত করতে পারেন এবং প্রথম ফাইলটি সরিয়ে ফেলতে পারেন:
csplit -sf file -n 1 large_file // /XYZ/+1
সৃষ্টি file0
, file1
এবং file2
কিন্তু file0
খালি যাতে আপনি নিরাপদে সরাতে পারেন:
rm -f file0
আধুনিক সহ ksh
এখানে উপরের ভিত্তিক উত্তরের একটি শেল বৈকল্পিক (অর্থাত্হীন sed
) রয়েছে sed
:
{ read in <##XYZ ; print "$in" ; cat >file2 ;} <largefile >file1
এবং ksh
এককভাবে আরও একটি বৈকল্পিক (অর্থাত্ বাদও দেওয়া cat
):
{ read in <##XYZ ; print "$in" ; { read <##"" ;} >file2 ;} <largefile >file1
(খাঁটি ksh
সমাধানটি বেশ পারফরম্যান্স বলে মনে হচ্ছে; ২.৪ গিগাবাইট পরীক্ষার ফাইলে এটি প্রয়োজনে 19-21 সেকেন্ডের sed
/ 39 cat
ভিত্তিক পদ্ধতির সাথে 39-47 সেকেন্ডের তুলনায় )।
read
এবং print
- আপনার এটি কেবল নিজের সমস্ত আউটপুটে যেতে দেওয়া উচিত। যদি আপনি সম্পূর্ণ এএসটি টুলকিটটি তৈরি করেন এবং ksh
বিল্টিনগুলি সমস্তই সংকলন করেন তবে পারফরম্যান্স আরও ভাল হয় - এটি আমার কাছে অদ্ভুত যে sed
আসলে তাদের মধ্যে নয়। তবে while <file do
আমার মত ধরণের স্টাফ দিয়ে আপনার sed
এতটা প্রয়োজন হবে না ...
awk
আপনার মানদণ্ডে পারফর্ম করলেন ? এবং যদিও আমি নিশ্চিত ksh
যে সম্ভবত এই লড়াইটি সবসময়ই জিতবে, আপনি যদি কোনও জিএনইউ ব্যবহার করেন তবে আপনার sed
পক্ষে খুব বেশি ন্যায্য নয় sed
- -u
জিএনইউ'র এনবার্ফার্ড পজিক্সলির কাছে একটি প্রস্রাব-দরিদ্র পদ্ধতির বিষয়টি নিশ্চিত করে যেখানে প্রোগ্রামটি বন্ধ হয়ে যায় সেখানে বর্ণনাকারীর অফসেটটি বাকী থাকে uring এটি - প্রোগ্রামটির নিয়মিত অপারেশনটি ধীর করার দরকার নেই - বাফারিং ঠিক আছে - সব sed
শেষ করার পরে বিবরণীর সন্ধান করতে হবে। জিএনইউ যে কারণেই হোক না কেন সেই মানসিকতাটিকে বিপরীত করে।
while
; মুদ্রণ স্পষ্টভাবে <##
পুনঃনির্দেশ অপারেটরের সংজ্ঞাযুক্ত পার্শ্ব প্রতিক্রিয়া হিসাবে সম্পন্ন করা হয় । এবং শুধুমাত্র ম্যাচিং লাইনের মুদ্রণ প্রয়োজন। (এইভাবে শেল বৈশিষ্ট্য বাস্তবায়ন Incl./excl এর সমর্থনের জন্য সবচেয়ে নমনীয়)) while
আমি একটি স্পষ্ট লুপটি উল্লেখযোগ্যভাবে ধীর হতে আশা করব (তবে পরীক্ষা করে দেখিনি) have
head
পরিবর্তে চেষ্টা করেছি read
; এটি শুধুমাত্র একটি সামান্য বিট ধীর বলে মনে হয়, কিন্তু এটি terser কোডের: { head -1 <##XYZ ; { read <##"" ;} >file4 ;} <largefile >file3
।
জিএনইউ সেড দিয়ে এটি ব্যবহার করে দেখুন:
sed -n -e '1,/XYZ/w file1' -e '/XYZ/,${/XYZ/d;w file2' -e '}' large_file
sed -e '1,/XYZ/{w file1' -e 'd}' large_file > file2
টার্গেটের প্যাটার্নটি মিলেছে কিনা তার উপর নির্ভর করে একটি সহজ হ্যাক হয় STDOUT বা STDERR এ মুদ্রণ করা। তারপরে আপনি শেলটির পুনর্নির্দেশ অপারেটরগুলি সেই অনুযায়ী আউটপুটটিকে পুনর্নির্দেশ করতে ব্যবহার করতে পারেন । উদাহরণস্বরূপ, পার্ল ধরে, ইনপুট ফাইল ডাকা f
এবং দুটি আউটপুট ফাইল f1
এবং f2
:
বিভাজন প্যাটার্নের সাথে মেলে এমন লাইনটি বাতিল করা:
perl -ne 'if(/XYZ/){$a=1; next} ; $a==1 ? print STDERR : print STDOUT;' f >f1 2>f2
ম্যাচ করা লাইন সহ:
perl -ne '$a=1 if /XYZ/; $a==1 ? print STDERR : print STDOUT;' f >f1 2>f2
বিকল্পভাবে, বিভিন্ন ফাইল হ্যান্ডলগুলিতে মুদ্রণ করুন:
বিভাজন প্যাটার্নের সাথে মেলে এমন লাইনটি বাতিল করা:
perl -ne 'BEGIN{open($fh1,">","f1");open($fh2,">","f2");}
if(/XYZ/){$a=1; next}$a==1 ? print $fh1 "$_" : print $fh2 "$_";' f
ম্যাচ করা লাইন সহ:
perl -ne 'BEGIN{open($fh1,">","f1"); open($fh2,">","f2");}
$a=1 if /XYZ/; $a==1 ? print $fh1 "$_" : print $fh2 "$_";' f
XYZ
লাইন আউটপুট অথবা না অন্তর্ভুক্ত হবে?