আসুন কয়েকটি উদাহরণ সহকারে তৈরি করা ইনপুট পাঠ্য সহ এক নজরে দেখুন:
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
ঘটে ...