1।
প্রথমটি:
for f in *; do
echo "$f"
done
নামক ফাইলের জন্য ব্যর্থ হয় -n, -eমত রূপ-nene এবং কিছু ব্যাশ স্থাপনার সঙ্গে, ফাইলের নাম ব্যাকস্ল্যাশ সম্বলিত।
দ্বিতীয়:
find * -prune | while read f; do
echo "$f"
done
এমনকি আরো মামলা ব্যর্থ (ফাইল নামক !, -H, -name,( , ফাইল নাম যে শুরু করলে বা ঐ খালি সঙ্গে শেষ বা সম্পর্কে newline অক্ষর ...)
এটি শেলটি প্রসারিত হয় *, findআর্গুমেন্ট হিসাবে প্রাপ্ত ফাইলগুলি মুদ্রণ করা ছাড়া কিছুই করে না। আপনি পাশাপাশি printf '%s\n'পরিবর্তে ব্যবহার করতে পারেন যা printfবিল্টিন হিসাবে রয়েছে অনেকগুলি আরোগ্যও এড়াতে পারে সম্ভাব্য ।
2।
এর সম্প্রসারণ *বাছাই করা হয়, যদি আপনার বাছাইয়ের প্রয়োজন না হয় তবে আপনি এটি কিছুটা দ্রুত তৈরি করতে পারেন। ইন zsh:
for f (*(oN)) printf '%s\n' $f
বা সহজভাবে:
printf '%s\n' *(oN)
bash যতদূর আমি বলতে পারি তার সমতুল্য নেই, তাই আপনাকে অবলম্বন করতে হবে find ।
3।
find . ! -name . -prune ! -name '.*' -print0 |
while IFS= read -rd '' f; do
printf '%s\n' "$f"
done
(উপরে একটি জিএনইউ / বিএসডি -print0অ-মানক এক্সটেনশন ব্যবহার করে)।
এটি এখনও একটি ফাইন্ড কমান্ড তৈরি এবং একটি ধীর while readলুপ ব্যবহার জড়িত , সুতরাং এটি forফাইলের তালিকা বিশাল না হওয়া পর্যন্ত লুপটি ব্যবহারের চেয়ে সম্ভবত ধীর হবে ।
4।
এছাড়াও, শেল ওয়াইল্ডকার্ড সম্প্রসারণের বিপরীতে, প্রতিটি ফাইলে findএকটি lstatসিস্টেম কল করবে , সুতরাং নোট-বাছাই করা তার পক্ষে ক্ষতিপূরণ পাবে এমন সম্ভাবনা কম।
জিএনইউ / বিএসডি-র findসাহায্যে, তাদের -maxdepthএক্সটেনশন ব্যবহার করে এড়ানো যায় যা এটি সংরক্ষণ করে একটি অপ্টিমাইজেশন ট্রিগার করবে lstat:
find . -maxdepth 1 ! -name '.*' -print0 |
while IFS= read -rd '' f; do
printf '%s\n' "$f"
done
কারণ findফাইলের নামগুলি খুঁজে পাওয়ার সাথে সাথে আউটপুট করা শুরু করে (স্টডিও আউটপুট বাফারিং ব্যতীত) যেখানে লুপটিতে আপনি যা করেন তা সময়সাপেক্ষ হয় এবং ফাইলের নামের তালিকাটি স্টডিও বাফারের চেয়ে বেশি হলে (4) / 8 কেবি)। সেক্ষেত্রে findসমস্ত ফাইল সন্ধান শেষ করার আগে লুপের মধ্যে প্রক্রিয়াজাতকরণ শুরু হবে । জিএনইউ এবং ফ্রিবিএসডি সিস্টেমগুলিতে, আপনি stdbufতাড়াতাড়ি হওয়ার কারণ হিসাবে ব্যবহার করতে পারেন (স্টিডিও বাফারিং অক্ষম করা)।
5।
এর সাথে প্রতিটি ফাইলের কমান্ড চালানোর জন্য পসিক্স / স্ট্যান্ডার্ড / পোর্টেবল উপায় findহ'ল -execপ্রিডিকেট ব্যবহার করা :
find . ! -name . -prune ! -name '.*' -exec some-cmd {} ';'
echoযদিও এর ক্ষেত্রে এটি শেলের লুপিংয়ের চেয়ে কম দক্ষ কারণ শেলের একটি বিল্টিন সংস্করণ থাকবে echoযখন findএকটি নতুন প্রক্রিয়া তৈরি করতে /bin/echoহবে এবং প্রতিটি ফাইলের জন্য এটি সম্পাদন করতে হবে।
আপনার যদি কয়েকটি কমান্ড চালানোর প্রয়োজন হয় তবে আপনি এটি করতে পারেন:
find . ! -name . -prune ! -name '.*' -exec cmd1 {} ';' -exec cmd2 {} ';'
তবে সাবধান থাকুন যে cmd2শুধুমাত্র cmd1সফল হলে মৃত্যুদন্ড কার্যকর করা হয়।
6।
প্রতিটি ফাইলের জন্য জটিল কমান্ডগুলি চালনার এক সাধারণ উপায় হ'ল এর সাথে শেল কল করা -exec ... {} +:
find . ! -name . -prune ! -name '.*' -exec sh -c '
for f do
cmd1 "$f"
cmd2 "$f"
done' sh {} +
এই সময়টি echoথেকে আমরা দক্ষ হয়ে ফিরে এসেছি যেহেতু আমরা shএকটি বিল্টিন ব্যবহার করছি এবং -exec +সংস্করণটি যত কম shসম্ভব স্প্যান হয়েছে ।
7।
ইন 200,000 ফাইলগুলির সাথে একটি ডিরেক্টরি আমার পরীক্ষার ext4 এই সংক্ষিপ্ত নামের সাথে, zshএক (অনুচ্ছেদ 2.), এ পর্যন্ত দ্রুততম দ্বারা প্রথম সহজ দ্বারা অনুসরণ for i in *লুপ (যদিও স্বাভাবিক হিসাবে, bashঅনেক যে জন্য অন্যান্য শাঁস তুলনায় ধীর যায়)।
findএটি খুঁজে পাওয়া ফাইলগুলি খুলবে না। এখানে বিপুল সংখ্যক ফাইলের প্রতি সম্মান সহকারে আমি আপনাকে কেবল কামড়ানো দেখতে পাচ্ছি তা হ'ল ARG_MAX ।