আসুন কয়েকটি উদাহরণ সহকারে তৈরি করা ইনপুট পাঠ্য সহ এক নজরে দেখুন:
text=' hello world\
foo\bar'
এটি দুটি লাইন, প্রথম স্থানটি দিয়ে শুরু এবং ব্যাকস্ল্যাশ দিয়ে শেষ। প্রথমে আসুন দেখে নেওয়া যাক আশেপাশে কোনও সতর্কতা ছাড়াই কী হয় read(তবে কোনও প্রকারের ঝুঁকি ছাড়াই printf '%s\n' "$text"সাবধানে মুদ্রণ করে ব্যবহার করা $text)। (নীচে, $ শেল প্রম্পট দেওয়া আছে।)
$ printf '%s\n' "$text" |
while read line; do printf '%s\n' "[$line]"; done
[hello worldfoobar]
readব্যাকস্ল্যাশগুলি খেয়েছে: ব্যাকস্ল্যাশ-নিউলাইনमुळे নিউলাইনটিকে উপেক্ষা করা যায় এবং ব্যাকস্ল্যাশ-যে কোনও কিছুই সেই প্রথম ব্যাকস্ল্যাশটিকে উপেক্ষা করে। ব্যাকস্ল্যাশগুলি বিশেষভাবে চিকিত্সা করা এড়াতে আমরা ব্যবহার করি read -r।
$ printf '%s\n' "$text" |
while read -r line; do printf '%s\n' "[$line]"; done
[hello world\]
[foo\bar]
এটি আরও ভাল, আমাদের প্রত্যাশা অনুযায়ী দুটি লাইন রয়েছে। দুটি লাইনে প্রায় কাঙ্ক্ষিত সামগ্রী থাকে: এর মধ্যে দ্বিগুণ স্থান helloএবং worldধরে রাখা হয়েছে, কারণ এটি lineভেরিয়েবলের মধ্যে রয়েছে। অন্যদিকে, প্রাথমিক স্থানটি খেয়ে ফেলেছিল। এটি কারণ আপনি readযতগুলি শব্দের পাঠ করেন তত পরিমাণে এটি ভেরিয়েবলগুলি ব্যয় করে, শেষের ভেরিয়েবলটিতে বাকী রেখাটি থাকে - তবে এটি এখনও প্রথম শব্দের সাথে শুরু হয়, অর্থাত প্রাথমিক স্পেসগুলি বাতিল করা হয়।
সুতরাং, প্রতিটি লাইন আক্ষরিকভাবে পড়ার জন্য, আমাদের নিশ্চিত করা দরকার যে কোনও শব্দ বিভাজন চলছে না। আমরা IFSভেরিয়েবলটি একটি খালি মানটিতে সেট করে এটি করি ।
$ printf '%s\n' "$text" |
while IFS= read -r line; do printf '%s\n' "[$line]"; done
[ hello world\]
[foo\bar]
আমরা অন্তর্নির্মিত IFS সময়কাল জন্য নির্দিষ্টভাবেread সেট কিভাবে নোট করুন । IFS= read -r lineসেট এনভায়রনমেন্ট ভেরিয়েবল IFSবিশেষভাবে কার্যকর করার জন্য (একটি খালি মান) read। এটি সাধারণ সাধারণ কমান্ড সিনট্যাক্সের একটি উদাহরণ : কমান্ডের নাম এবং এর যুক্তিগুলির পরে একটি (সম্ভবত শূন্য) পরিবর্তনশীল অ্যাসাইনমেন্টগুলির অনুক্রম (এছাড়াও আপনি যে কোনও বিন্দুতে পুনর্নির্দেশে ফেলে দিতে পারেন)। যেহেতু readএকটি অন্তর্নির্মিত তাই পরিবর্তনশীল আসলে কোনও বাহ্যিক প্রক্রিয়ার পরিবেশে শেষ হয় না; তবুও $IFSযতক্ষণ readনির্বাহ করা হয় সেখানে আমরা যা নির্ধারণ করছি তার মান ¹ দ্রষ্টব্য যে readকোনও বিশেষ অন্তর্নির্মিত নয় , সুতরাং এই নিয়োগটি কেবলমাত্র তার সময়কালের জন্য স্থায়ী হয়।
সুতরাং আমরা IFSঅন্যান্য নির্দেশাবলীর উপর নির্ভর করতে পারে তার মান পরিবর্তন না করার জন্য যত্ন নিচ্ছি । এই কোডটি আশেপাশের কোডটি IFSপ্রাথমিকভাবে কী সেট করেছে তা কার্যকর হবে এবং লুপের অভ্যন্তরীণ কোডটি নির্ভর করে যদি এটি কোনও সমস্যা করে না IFS।
এই কোড স্নিপেটের সাথে বৈসাদৃশ্য করুন, যা কোলন-বিচ্ছিন্ন পথে ফাইল দেখায়। ফাইলের নামের তালিকা একটি ফাইল থেকে পঠিত হয়, প্রতি লাইনে একটি ফাইলের নাম।
IFS=":"; set -f
while IFS= read -r name; do
for dir in $PATH; do
## At this point, "$IFS" is still ":"
if [ -e "$dir/$name" ]; then echo "$dir/$name"; fi
done
done <filenames.txt
যদি লুপটি ছিল while IFS=; read -r name; do …, তবে কোলন-বিচ্ছিন্ন উপাদানগুলিতে for dir in $PATHবিভক্ত হবে না $PATH। কোডটি যদি ছিল তবে IFS=; while read …এটি আরও স্পষ্ট হবে যা লুপের বডিতে IFSসেট করা নেই :।
অবশ্যই, IFSকার্যকর করার পরে এর মানটি পুনরুদ্ধার করা সম্ভব হবে read। তবে এর জন্য পূর্ববর্তী মানটি জানা দরকার যা অতিরিক্ত প্রচেষ্টা। IFS= readসহজ উপায় (এবং, স্বাচ্ছন্দ্যে, সবচেয়ে সংক্ষিপ্ততম উপায়))
¹ এবং, যদি readকোনও আটকা পড়া সংকেত দ্বারা বাধাগ্রস্ত হয়, সম্ভবত ট্র্যাপটি কার্যকর করা অবস্থায় - এটি পসিক্স দ্বারা নির্দিষ্ট করা হয়নি এবং বাস্তবে শেলের উপর নির্ভর করে।
while IFS=X readবিভক্ত হয় নাX, তবেwhile IFS=X; readঘটে ...