এই উত্তরটি নিম্নলিখিত অংশে আসে:
- এর বেসিক ব্যবহার
-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 {} +