লিনাক্স ব্যবহারকারীদের জন্য 2020 আপডেট করুন:
আপনার যদি বাশ (৪.৪-আলফা বা আরও ভাল) সংস্করণ থাকে তবে আপনি সম্ভবত লিনাক্সে থাকলে এটি করা উচিত, তবে আপনার উচিত বেনজামিন ডাব্লু এর উত্তরটি ব্যবহার করা ।
আপনি যদি ম্যাক ওএসে থাকেন তবে আমি কোনটি এখনও পরীক্ষা করে দেখেছি - এখনও ব্যাশ ৩.২ ব্যবহার করেছেন বা অন্যথায় কোনও পুরানো ব্যাশ ব্যবহার করছেন তবে পরবর্তী বিভাগে চালিয়ে যান।
4.3 বা তার আগে বাশার উত্তর
এখানে আউটপুট পাওয়ার জন্য এক সমাধান find
একটি মধ্যে bash
অ্যারে:
array=()
while IFS= read -r -d $'\0'; do
array+=("$REPLY")
done < <(find . -name "${input}" -print0)
এটি মুশকিল কারণ সাধারণভাবে ফাইলের নামগুলিতে স্পেস, নতুন লাইন এবং অন্যান্য স্ক্রিপ্ট-প্রতিকূল অক্ষর থাকতে পারে। find
ফাইলের নামগুলি একে অপরের থেকে নিরাপদে পৃথকভাবে ব্যবহার এবং ব্যবহারের একমাত্র উপায় হ'ল -print0
ফাইল নামগুলি নাল অক্ষর দ্বারা পৃথক করা মুদ্রণ করা। যদি ব্যাশের readarray
/ mapfile
ফাংশনগুলি নাল-বিচ্ছিন্ন স্ট্রিংগুলিকে সমর্থন করে তবে এটি কোনও অসুবিধে হবে না। বাশের read
কাজটি করে এবং এটি আমাদের উপরের লুপের দিকে নিয়ে যায়।
[এই উত্তরটি মূলত ২০১৪ সালে লেখা হয়েছিল you আপনার কাছে বাশের সাম্প্রতিক সংস্করণ থাকলে নীচের আপডেটটি দেখুন]]
কিভাবে এটা কাজ করে
প্রথম লাইনটি একটি খালি অ্যারে তৈরি করে: array=()
প্রতিবার read
স্টেটমেন্টটি কার্যকর করা হলে, স্ট্যান্ডার্ড ইনপুট থেকে একটি নাল-বিচ্ছিন্ন ফাইলের নামটি পড়া হয়। -r
বিকল্প বলে read
ব্যাকস্ল্যাশ অক্ষর একা ছেড়ে। -d $'\0'
বলে read
যে ইনপুট নাল বিভাজিত হতে হবে। যেহেতু আমরা নাম বাদ read
, শেল ডিফল্ট নামে ইনপুট রাখে: REPLY
।
array+=("$REPLY")
বিবৃতি অ্যারের নতুন ফাইলের নাম appends array
।
চূড়ান্ত লাইনটি পুনর্নির্দেশ এবং কমান্ড প্রতিস্থাপনের সাথে একত্রিত find
করে while
লুপের স্ট্যান্ডার্ড ইনপুটটির আউটপুট সরবরাহ করে ।
প্রক্রিয়া বিকল্প ব্যবহার কেন?
আমরা যদি প্রক্রিয়া বিকল্প ব্যবহার না করি তবে লুপটি এইভাবে লেখা যেতে পারে:
array=()
find . -name "${input}" -print0 >tmpfile
while IFS= read -r -d $'\0'; do
array+=("$REPLY")
done <tmpfile
rm -f tmpfile
উপরের আউটপুটটি find
একটি অস্থায়ী ফাইলে সংরক্ষণ করা হয় এবং সেই ফাইলটি লুপের স্ট্যান্ডার্ড ইনপুট হিসাবে ব্যবহৃত হয়। প্রক্রিয়া প্রতিস্থাপনের ধারণাটি এই জাতীয় অস্থায়ী ফাইলগুলিকে অপ্রয়োজনীয় করে তোলা। সুতরাং, এর পরিবর্তে while
লুপটি এর স্টিডিনটি পেতে tmpfile
, আমরা এটির স্টিডিনটি পেতে পারি <(find . -name ${input} -print0)
।
প্রক্রিয়া প্রতিস্থাপন ব্যাপকভাবে দরকারী। কমান্ড একটি ফাইল থেকে পড়তে চায় এমন অনেক জায়গায় , আপনি <(...)
কোনও ফাইলের নামের পরিবর্তে প্রক্রিয়া বিকল্পটি নির্দিষ্ট করতে পারেন । একটি অনুরূপ ফর্ম রয়েছে, >(...)
এটি একটি ফাইলের নামের জায়গায় ব্যবহার করা যেতে পারে যেখানে কমান্ড ফাইলটি লিখতে চায় ।
অ্যারেগুলির মতো, প্রক্রিয়া প্রতিস্থাপন বাশ এবং অন্যান্য উন্নত শেলগুলির বৈশিষ্ট্য। এটি পসিক্স স্ট্যান্ডার্ডের অংশ নয়।
বিকল্প: সর্বশেষ পাইপ
যদি ইচ্ছা lastpipe
হয় তবে প্রক্রিয়া বিকল্পের পরিবর্তে ব্যবহার করা যেতে পারে (টুপি টিপ: সিজার ):
set +m
shopt -s lastpipe
array=()
find . -name "${input}" -print0 | while IFS= read -r -d $'\0'; do array+=("$REPLY"); done; declare -p array
shopt -s lastpipe
বর্তমান শেলের পাইপলাইনে (ব্যাকগ্রাউন্ড নয়) সর্বশেষ কমান্ড চালাতে বাশকে বলে। এইভাবে, array
পাইপলাইনটি সম্পূর্ণ হওয়ার পরে অবশেষে অস্তিত্ব রয়েছে। কারণ lastpipe
কেবল তখনই কার্যকর হয় যদি কাজের নিয়ন্ত্রণ বন্ধ থাকে, আমরা চালাই set +m
। (কোনও স্ক্রিপ্টে, কমান্ড লাইনের বিপরীতে, চাকরি নিয়ন্ত্রণ ডিফল্টভাবে বন্ধ রয়েছে))
অতিরিক্ত নোট
নিম্নলিখিত কমান্ড শেল অ্যারে নয় শেল পরিবর্তনশীল তৈরি করে:
array=`find . -name "${input}"`
যদি আপনি কোনও অ্যারে তৈরি করতে চান তবে আপনাকে খুঁজে পাওয়ার আউটপুটটি জুড়ে প্যারেন্স লাগাতে হবে। সুতরাং, নির্বোধভাবে, একটি পারে:
array=(`find . -name "${input}"`)
সমস্যাটি হ'ল শেল এর ফলাফলগুলিতে শব্দের বিভাজন সম্পাদন করে find
যাতে অ্যারের উপাদানগুলিকে আপনি চান তা গ্যারান্টিযুক্ত না করে।
2019 আপডেট করুন
সংস্করণ ৪.৪-আলফা দিয়ে শুরু করে, বাশ এখন একটি -d
বিকল্প সমর্থন করে যাতে উপরের লুপটি আর প্রয়োজন হয় না। পরিবর্তে, একটি ব্যবহার করতে পারেন:
mapfile -d $'\0' array < <(find . -name "${input}" -print0)
এ সম্পর্কিত আরও তথ্যের জন্য, দয়া করে বেনজামিন ডাব্লু এর উত্তর দেখুন (এবং উপস্থাপন করুন) ।