এই উত্তরটি নিম্নলিখিত অংশে আসে:
- এর বেসিক ব্যবহার
-exec
-execসাথে সংমিশ্রণে ব্যবহার করাsh -c
- ব্যবহার
-exec ... {} +
- ব্যবহার
-execdir
এর বেসিক ব্যবহার -exec
-execবিকল্প তার আর্গুমেন্ট হিসাবে ঐচ্ছিক আর্গুমেন্ট সহ একটি বহিস্থিত ইউটিলিটি লাগে এবং সঞ্চালন করে।
যদি স্ট্রিং {}প্রদত্ত কমান্ডের যে কোনও জায়গায় উপস্থিত থাকে, তবে এর প্রতিটি উদাহরণ বর্তমানে প্রক্রিয়াকরণ হওয়া প্যাথনাম দ্বারা প্রতিস্থাপন করা হবে (উদাঃ ./some/path/FILENAME)। বেশিরভাগ শেলগুলিতে দুটি চরিত্রের {}উদ্ধৃতি দেওয়ার প্রয়োজন হয় না।
কমান্ড একটি দিয়ে শেষ করা হবে ;জন্য find(সেখানে আরও বিকল্প পরে হতে পারে) যেখানে জানতে এটা শেষ। ;শেল থেকে রক্ষা করতে , এটি হিসাবে \;বা হিসাবে উদ্ধৃত করা প্রয়োজন ';', অন্যথায় শেল এটি findকমান্ডের শেষ হিসাবে দেখবে ।
উদাহরণ ( \প্রথম দুটি লাইনের শেষে কেবল লাইন ধারাবাহিকতার জন্য):
find . -type f -name '*.txt' \
-exec grep -q 'hello' {} ';' \
-exec cat {} ';'
এটি সমস্ত নিয়মিত ফাইল ( -type f) যার নাম *.txtবর্তমান ডিরেক্টরিতে বা নীচে প্যাটার্নের সাথে মেলে । এরপরে এটি পরীক্ষা করে helloদেখা গেছে যে কোন স্ট্রিং ফাইল পাওয়া গিয়েছে তা ব্যবহার করে grep -q(যা কোনও আউটপুট উত্পাদন করে না, কেবলমাত্র একটি প্রস্থান স্থিতি)। স্ট্রিং ধারণ করে এমন ফাইলগুলির catজন্য টার্মিনালে ফাইলের সামগ্রীগুলি আউটপুট দিতে কার্যকর করা হবে।
প্রতিটি -execএছাড়াও pathnames দ্বারা পাওয়া একটি "পরীক্ষা" মত কাজ করে find, ঠিক এরকমই -typeএবং -nameআছে। যদি কমান্ডটি শূন্য প্রস্থান স্থিতি দেয় ("সাফল্য নির্দেশ করে), findকমান্ডের পরবর্তী অংশটি বিবেচনা করা হয়, অন্যথায় findকমান্ডটি পরবর্তী পথের নামের সাথে চালিয়ে যায়। এটি স্ট্রিং রয়েছে এমন ফাইলগুলি খুঁজে পেতে helloঅন্য সমস্ত ফাইল উপেক্ষা করার জন্য উপরের উদাহরণে ব্যবহৃত হয় is
উপরের উদাহরণটি দুটি সাধারণ ব্যবহারের ক্ষেত্রে চিত্রিত করে -exec:
- অনুসন্ধান আরও সীমাবদ্ধ করার পরীক্ষা হিসাবে।
- সন্ধানকারী পথের নামটিতে কোনও ধরণের ক্রিয়া সম্পাদন করা (সাধারণত, তবে
findকমান্ডের শেষে প্রয়োজন হয় না )।
-execসাথে সংমিশ্রণে ব্যবহার করাsh -c
যে আদেশটি -execকার্যকর করতে পারে তা alচ্ছিক আর্গুমেন্ট সহ একটি বাহ্যিক ইউটিলিটিতে সীমাবদ্ধ। শেল বিল্ট-ইনগুলি, ফাংশন, শর্তসাপেক্ষ, পাইপলাইন, পুনর্নির্দেশগুলি ইত্যাদি সরাসরি ব্যবহার করা -execসম্ভব নয়, যদি না sh -cশিশু শেলের মতো কিছুতে আবৃত থাকে ।
যদি bashবৈশিষ্ট্যগুলি প্রয়োজন হয় তবে তার bash -cজায়গায় ব্যবহার করুন sh -c।
sh -c/bin/shকমান্ড লাইনে প্রদত্ত স্ক্রিপ্ট দিয়ে চালায় , তারপরে সেই স্ক্রিপ্টে alচ্ছিক কমান্ড লাইন আর্গুমেন্ট।
sh -cনিজেই ব্যবহার করার একটি সাধারণ উদাহরণ find:
sh -c 'echo "You gave me $1, thanks!"' sh "apples"
এটি শিশু শেল স্ক্রিপ্টে দুটি আর্গুমেন্ট পাস করে:
স্ট্রিং sh। এটি $0স্ক্রিপ্টের অভ্যন্তরের মতোই উপলব্ধ হবে এবং যদি অভ্যন্তরীণ শেলটি একটি ত্রুটি বার্তা আউটপুট করে তবে এটি এই স্ট্রিংটির সাথে এটি উপসর্গ করবে।
যুক্তি applesহিসাবে পাওয়া যায় $1লিপিতে, এবং আরো আর্গুমেন্ট, তবে এই হিসাবে উপলব্ধ হতো হয়েছে $2, $3ইত্যাদি তারা তালিকায় পাওয়া যাবে "$@"(-setup জন্য $0যার অংশ হবে না "$@")।
এই সঙ্গে একযোগে দরকারী -execকরুন কারণ এটি আমাদের ইচ্ছামত জটিল স্ক্রিপ্ট pathnames দ্বারা পাওয়া উপর কাজ করে করতে পারবেন find।
উদাহরণ: নির্দিষ্ট ফাইলের প্রত্যয়যুক্ত সমস্ত নিয়মিত ফাইল সন্ধান করুন এবং সেই ফাইলের প্রত্যয়টি অন্য কয়েকটি প্রত্যয়তে পরিবর্তন করুন, যেখানে প্রত্যয়গুলি ভেরিয়েবলগুলিতে রাখা হয়েছে:
from=text # Find files that have names like something.text
to=txt # Change the .text suffix to .txt
find . -type f -name "*.$from" -exec sh -c 'mv "$3" "${3%.$1}.$2"' sh "$from" "$to" {} ';'
অভ্যন্তরীণ স্ক্রিপ্ট ভিতরে, $1স্ট্রিং হতে হবে text, $2স্ট্রিং হতে হবে txtএবং $3যাই হোক না কেন পথনাম হবে findআমাদের জন্য পাওয়া গেছে। প্যারামিটার সম্প্রসারণ ${3%.$1}পথটির নাম নেবে এবং এ .textথেকে প্রত্যয়টি সরিয়ে ফেলবে ।
অথবা, dirname/ ব্যবহার করে basename:
find . -type f -name "*.$from" -exec sh -c '
mv "$3" "$(dirname "$3")/$(basename "$3" ".$1").$2"' sh "$from" "$to" {} ';'
বা, অভ্যন্তরীণ স্ক্রিপ্টে যুক্ত ভেরিয়েবলগুলি সহ:
find . -type f -name "*.$from" -exec sh -c '
from=$1; to=$2; pathname=$3
mv "$pathname" "$(dirname "$pathname")/$(basename "$pathname" ".$from").$to"' sh "$from" "$to" {} ';'
নোট করুন যে এই শেষ প্রকরণের মধ্যে, বহিরাগত স্ক্রিপ্টের একই নামগুলির সাথে ভেরিয়েবলগুলি fromএবং toচাইল্ড শেলের মধ্যে ভেরিয়েবলগুলি থেকে পৃথক।
উপরে থেকে একটি অবাধ জটিল স্ক্রিপ্ট কলিং সঠিক পথ -execসঙ্গে find। findমত একটি লুপ ব্যবহার
for pathname in $( find ... ); do
ত্রুটি প্রবণ এবং অবহেলিত (ব্যক্তিগত মতামত)। এটি হোয়াইটস্পেসে ফাইলের নামগুলি বিভক্ত করছে, ফাইলের নাম গ্লোব্বিং করছে, এবং findলুপের প্রথম পুনরাবৃত্তি চালানোর আগে শেলটিকে পুরো ফলাফলটি প্রসারিত করতে বাধ্য করে ।
আরো দেখুন:
ব্যবহার -exec ... {} +
;শেষে দ্বারা প্রতিস্থাপিত হতে পারে +। এটি findপ্রতিটি প্রাপ্ত পাথের নামের চেয়ে একবারের চেয়ে যতগুলি আর্গুমেন্ট (পাথের নাম পাওয়া গেছে) দিয়ে প্রদত্ত কমান্ডটি কার্যকর করতে পারে। স্ট্রিংটি {} এটি +কাজ করার জন্য ঠিক আগে ঘটতে হবে ।
find . -type f -name '*.txt' \
-exec grep -q 'hello' {} ';' \
-exec cat {} +
এখানে, findফলস্বরূপ পাথের নামগুলি সংগ্রহ করা হবে এবং catএকবারে যতগুলি সম্ভব সম্ভবকে কার্যকর করা হবে।
find . -type f -name "*.txt" \
-exec grep -q "hello" {} ';' \
-exec mv -t /tmp/files_with_hello/ {} +
একইভাবে এখানে, mvযতবার সম্ভব কার্যকর করা হবে। এই শেষ উদাহরণটির জন্য mvকোর্টিলগুলি (যা -tবিকল্পটিকে সমর্থন করে ) থেকে জিএনইউ প্রয়োজন ।
-exec sh -c ... {} +ইচ্ছামত জটিল স্ক্রিপ্টের সাহায্যে প্যাথনামগুলির একটি সেট লুপ করার একটি কার্যকর উপায় Using
বেসিকগুলি ব্যবহার করার সময় একই রকম -exec sh -c ... {} ';', তবে স্ক্রিপ্টটি এখন আর্গুমেন্টগুলির অনেক বেশি দীর্ঘ তালিকা গ্রহণ করে। "$@"স্ক্রিপ্টের ভিতরে লুপ করে এগুলি লুপ করা যায় ।
ফাইলের নাম প্রত্যয় পরিবর্তন করে এমন সর্বশেষ বিভাগ থেকে আমাদের উদাহরণ:
from=text # Find files that have names like something.text
to=txt # Change the .text suffix to .txt
find . -type f -name "*.$from" -exec sh -c '
from=$1; to=$2
shift 2 # remove the first two arguments from the list
# because in this case these are *not* pathnames
# given to us by find
for pathname do # or: for pathname in "$@"; do
mv "$pathname" "${pathname%.$from}.$to"
done' sh "$from" "$to" {} +
ব্যবহার -execdir
এছাড়াও রয়েছে -execdir(বেশিরভাগ findরূপগুলি দ্বারা প্রয়োগ করা হয় তবে মানক বিকল্প নয়)।
এটি -execপ্রদত্ত শেল কমান্ডটি তার বর্তমান কার্যকরী ডিরেক্টরি হিসাবে {}পাওয়া পাথের findনামের ডিরেক্টরিতে কার্যকর করা হয় এবং এটিতে কোনও পাথ ছাড়াই পাওয়া পথের বেসনামটি থাকবে (তবে জিএনইউ এখনও বেসনটির সাথে পূর্ব নামটি উপস্থাপন করবে) ./, বিএসডি সহ findএটা করবে না)।
উদাহরণ:
find . -type f -name '*.txt' \
-execdir mv {} done-texts/{}.done \;
এটি প্রতিটি পাওয়া ফাইল-ফাইল একই ডিরেক্টরিতে*.txt প্রাক-বিদ্যমান done-textsসাব - ডিরেক্টরিতে স্থানান্তরিত করবে যেখানে ফাইলটি পাওয়া গেছে । এতে প্রত্যয় যুক্ত করে ফাইলটিরও নামকরণ .doneকরা হবে।
এটি করা একটু কৌশলযুক্ত -execহবে কারণ ফাইলটির {}নতুন নাম তৈরি করতে আমাদের খুঁজে পাওয়া ফাইলটির বেসনামটি বের করতে হবে। ডিরেক্টরিটি সঠিকভাবে {}সনাক্ত করতে আমাদের কাছ থেকে ডিরেক্টরি নামও প্রয়োজন done-texts।
এর সাথে এ জাতীয় -execdirকিছু জিনিস সহজ হয়ে যায়।
-execপরিবর্তে ব্যবহার করে সংশ্লিষ্ট অপারেশন -execdirএকটি শিশু শেল নিয়োগ করতে হবে:
find . -type f -name '*.txt' -exec sh -c '
for name do
mv "$name" "$( dirname "$name" )/done-texts/$( basename "$name" ).done"
done' sh {} +
বা,
find . -type f -name '*.txt' -exec sh -c '
for name do
mv "$name" "${name%/*}/done-texts/${name##*/}.done"
done' sh {} +