TL; DR: এর -exec rm
পরিবর্তে সবচেয়ে ভাল উপায় ব্যবহার করা -delete
।
find a \( -name b -prune \) -o -type f -exec rm {} +
ব্যাখ্যা:
কেন খুঁজে না নালিশ যখন আপনি ব্যবহার করতে চেষ্টা -delete
সঙ্গে -prune
?
সংক্ষিপ্ত উত্তর: কারণ -delete
বোঝায় -depth
এবং অকার্যকর করে -depth
তোলে -prune
।
আমরা দীর্ঘ উত্তরে আসার আগে প্রথমে এবং এর বাইরে অনুসন্ধানের আচরণটি পর্যবেক্ষণ করুন -depth
:
$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2
একক ডিরেক্টরিতে অর্ডার সম্পর্কে কোনও গ্যারান্টি নেই। তবে একটি গ্যারান্টি রয়েছে যে কোনও ডিরেক্টরিতে এর সামগ্রীগুলির আগে প্রক্রিয়া করা হয়। foo/
যেকোন আগে foo/*
এবং তার foo/bar
আগে নোট করুন foo/bar/*
।
এটি দিয়ে বিপরীত হতে পারে -depth
।
$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/
নোট করুন যে এখন সব foo/*
আগে উপস্থিত foo/
। একই সাথে foo/bar
।
দীর্ঘ উত্তর:
-prune
ডিরেক্টরিতে নামা থেকে অনুসন্ধানকে বাধা দেয়। অন্য কথায় -prune
ডিরেক্টরিগুলির বিষয়বস্তু এড়িয়ে যায়। আপনার ক্ষেত্রে -name b -prune
নামের সাথে কোনও ডিরেক্টরিতে নামা থেকে অনুসন্ধানকে বাধা দেয় b
।
-depth
ডিরেক্টরিটি নিজেই ডিরেক্টরি আগে তৈরি করার জন্য ডিরেক্টরিগুলির বিষয়বস্তুগুলি প্রক্রিয়া করে। এর অর্থ সময় অনুসারে ডিরেক্টরিতে প্রবেশের প্রক্রিয়া শুরু করে b
এর সামগ্রীগুলি ইতিমধ্যে প্রক্রিয়াভুক্ত হয়েছে। সুতরাং কার্যকরভাবে -prune
এটি অকার্যকর -depth
।
-delete
বোঝায় -depth
যাতে এটি প্রথমে ফাইলগুলি মুছতে পারে এবং তারপরে খালি ডিরেক্টরিটি। -delete
খালি নয় এমন ডিরেক্টরি মুছতে অস্বীকার করে। আমার ধারণা, -delete
খালি নয় এমন ডিরেক্টরি মুছে ফেলার জন্য এবং / অথবা -delete
বোঝাতে বাধা দেওয়ার জন্য একটি বিকল্প যুক্ত করা সম্ভব হবে -depth
। তবে সেটা অন্য গল্প।
আপনি যা চান তা অর্জনের আরও একটি উপায় রয়েছে:
find a -not -path "*/b*" -type f -delete
এটি মনে রাখা সহজ বা নাও হতে পারে।
এই কমান্ডটি এখনও ডিরেক্টরিতে b
নেমেছে এবং কেবলমাত্র -not
সেগুলি প্রত্যাখ্যান করার জন্য এতে প্রতিটি ফাইলই প্রসেস করে । ডিরেক্টরিটি b
বিশাল হলে এটি পারফরম্যান্সের সমস্যা হতে পারে ।
-path
চেয়ে আলাদাভাবে কাজ করে -name
। -name
পুরো নামের সাথে মিল থাকা অবস্থায় কেবল নামের সাথে (ফাইল বা ডিরেক্টরি) -path
মেলে। উদাহরণস্বরূপ পথ পর্যবেক্ষণ করুন /home/lesmana/foo/bar
। -name -bar
নাম আছে কারণ মিলবে bar
। -path "*/foo*"
মিলবে কারণ স্ট্রিং /foo
পথে আছে। -path
এটি ব্যবহার করার আগে আপনার কিছুটা জটিলতা বোঝা উচিত। find
আরও তথ্যের জন্য ম্যান পৃষ্ঠা পড়ুন ।
সাবধান থাকুন যে এটি 100% বুদ্ধিমানের নয়। "মিথ্যা ধনাত্মক" হওয়ার সম্ভাবনা রয়েছে। কমান্ডটি উপরে যেভাবে লেখা হয়েছে তাতে কোনও ধরণের পিতৃ ডিরেক্টরি রয়েছে এমন কোনও ফাইল এড়িয়ে যাবে যা নাম b
(ধনাত্মক) দিয়ে শুরু হচ্ছে । তবে b
গাছের অবস্থান নির্বিশেষে কোন নামটি শুরু হচ্ছে এমন কোনও ফাইল এড়িয়ে যাবে (মিথ্যা পজিটিভ)। এটির চেয়ে আরও ভাল অভিব্যক্তি লিখে স্থির করা যায় "*/b*"
। পাঠকের জন্য অনুশীলন হিসাবে এটি বাকি রয়েছে।
আমি ধরে নিয়েছি যে আপনি ব্যবহার করেছেন a
এবং b
স্থানধারক হিসাবে এবং আসল নামগুলি আরও বেশি পছন্দ allosaurus
এবং brachiosaurus
। আপনি যদি brachiosaurus
এর জায়গায় রাখেন b
তবে মিথ্যা পজিটিভের পরিমাণ মারাত্মকভাবে হ্রাস পাবে।
কমপক্ষে মিথ্যা পজিটিভগুলি মুছে ফেলা হবে না , সুতরাং এটি তাত্পর্যজনক হবে না। তদ্ব্যতীত, আপনি প্রথমে কমান্ডটি চালিয়ে মিথ্যা পজিটিভগুলি পরীক্ষা করতে পারেন -delete
(তবে অন্তর্ভুক্ত রাখার কথা মনে রাখবেন -depth
) এবং আউটপুট পরীক্ষা করতে পারেন।
find a -not -path "*/b*" -type f -depth
a
বাদে সব কিছু অন্তর্ভুক্ত করবেনa/b
?