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?