Linux-এ find কমান্ড: নাম, আকার ও তারিখ দিয়ে ফাইল খোঁজা — উদাহরণ
find কমান্ড ডিরেক্টরি ট্রি ঘুরে শর্ত মেনে ফাইল বেছে নেয়: find /path -name '*.log' খোঁজে নাম দিয়ে, -type f শুধু ফাইল, -size +100M 100 MB-এর বড়, -mtime -7 গত এক সপ্তাহে বদলানো। শর্তগুলো একসঙ্গে ব্যবহার করা যায়, আর পাওয়া ফাইলের ওপর -exec, -delete বা xargs দিয়ে কাজ করা যায়।
find কমান্ড ডিরেক্টরি ট্রি ঘুরে নাম, ধরন, আকার, পরিবর্তনের তারিখ, মালিক ও অনুমতির শর্ত মিলিয়ে ফাইল খুঁজে বের করে। সাধারণ কাঠামো — find [কোথায় খুঁজবে] [শর্তসমূহ] [কাজ]। নিচে লিনাক্সে find-এর উদাহরণ দেওয়া হলো সাধারণ কাজের জন্য: কনফিগ ফাইল খোঁজা, পুরনো লগ মোছা, ডিস্কের জায়গা কী দখল করছে তা বের করা।
find কমান্ডের সিনট্যাক্স
find /var/log -type f -name '*.log' -mtime +30 -print
ধাপে ধাপে দেখা যাক:
/var/log— শুরুর বিন্দু। একাধিক ডিরেক্টরি পরপর দেওয়া যায়, অথবা.(বর্তমান)। পথ না দিলে GNU find বর্তমান ডিরেক্টরিতে খোঁজে।-type f -name '*.log' -mtime +30— শর্তসমূহ (ডকুমেন্টেশনে এদের বলা হয় টেস্ট)। ডিফল্টভাবে এদের মধ্যে “এবং” সম্পর্ক থাকে।-print— কাজ: পাথ প্রিন্ট করা। অন্য কোনো কাজ না থাকলে এটি নিজে থেকেই বসে যায়।
find রিকার্সিভলি সব ভেতরের ডিরেক্টরিতে যায়। সাধারণ ব্যবহারকারী হিসেবে সিস্টেমের পথে চালালে আউটপুট Permission denied বার্তায় ভরে যায়। ত্রুটির স্ট্রিম সরিয়ে দিয়ে এটি এড়ানো যায়:
find / -name 'nginx.conf' 2>/dev/null
নাম দিয়ে খোঁজা: -name ও -iname
শর্ত -name শুধু ফাইলের নাম (পথ ছাড়া) প্যাটার্নের সঙ্গে মেলায়। প্যাটার্নে * (যেকোনো অক্ষর), ? (একটি অক্ষর) ও [abc] (তালিকার একটি অক্ষর) চলে।
# হুবহু নাম
find /etc -name 'hosts'
# সব .conf ফাইল
find /etc -name '*.conf'
# ছোট-বড় হাতের অক্ষর উপেক্ষা করে: README.md, readme.MD, Readme.md
find ~/projects -iname 'readme.md'
# report_1.csv ... report_9.csv
find . -name 'report_?.csv'
প্যাটার্ন সবসময় উদ্ধৃতিচিহ্নে লিখুন। উদ্ধৃতি না থাকলে shell বর্তমান ডিরেক্টরির ফাইল দিয়ে *.conf-কে আগেই প্রসারিত করে ফেলে, তখন find প্যাটার্ন না পেয়ে ফাইলের নামের তালিকা পায় — ফল হয় অপ্রত্যাশিত, নইলে paths must precede expression ত্রুটি।
পথ দিয়ে খোঁজা: -path ও -regex
শুধু নাম নয়, ডিরেক্টরিও গুরুত্বপূর্ণ হলে -path ব্যবহার করুন — এটি পুরো পথের সঙ্গে প্যাটার্ন মেলায়:
# শুধু src ডিরেক্টরির ভেতরের .js ফাইল
find . -path '*/src/*' -name '*.js'
জটিল প্যাটার্নের জন্য আছে -regex (রেগুলার এক্সপ্রেশনও পুরো পথের ওপর কাজ করে) এবং কেস-অসংবেদনশীল -iregex:
find . -regextype posix-extended -regex '.*\.(jpg|jpeg|png)$'
একটি ডিরেক্টরি বাদ দেওয়া
find যেন node_modules বা .git-এ না ঢোকে, তার জন্য -prune ব্যবহার হয়:
find . -path ./node_modules -prune -o -name '*.js' -print
পড়ুন এভাবে: “যদি পথ ./node_modules হয়, তাতে নামবে না; নইলে (-o) *.js ফাইল প্রিন্ট করো”। শেষে স্পষ্ট -print থাকা জরুরি, নইলে বাদ দেওয়া ডিরেক্টরিটিও আউটপুটে চলে আসবে। সহজ কিন্তু ধীর বিকল্প — -not -path '*/node_modules/*': find ডিরেক্টরিটি তবুও ঘুরে দেখে, শুধু ফলাফল ছাঁকে।
ধরন দিয়ে খোঁজা: -type
| মান | যা খোঁজে |
|---|---|
-type f | সাধারণ ফাইল |
-type d | ডিরেক্টরি |
-type l | সিম্বলিক লিংক |
-type s | সকেট |
-type p | নামযুক্ত পাইপ (FIFO) |
# শুধু logs নামের ডিরেক্টরি
find / -type d -name 'logs' 2>/dev/null
# খালি ফাইল ও খালি ডিরেক্টরি
find . -type f -empty
find . -type d -empty
# ভাঙা সিম্বলিক লিংক
find . -xtype l
আকার দিয়ে খোঁজা: -size
-size একটি সংখ্যা নেয় সঙ্গে একটি প্রত্যয়: c — বাইট, k — কিলোবাইট, M — মেগাবাইট, G — গিগাবাইট। চিহ্ন + মানে “বড়”, - মানে “ছোট”, চিহ্ন না থাকলে “ঠিক সমান”।
# পুরো সিস্টেমে 100 MB-এর বড় ফাইল
find / -type f -size +100M 2>/dev/null
# 10 থেকে 50 MB-এর মধ্যে
find . -type f -size +10M -size -50M
# 1 KB-এর ছোট
find . -type f -size -1k
একটি সূক্ষ্মতা আছে: আকার একক অনুযায়ী ওপরের দিকে গোল করা হয়। তাই -size -1M শুধু খালি ফাইল খুঁজবে — যেকোনো অখালি ফাইল গোল হয়ে “অন্তত 1 মেগাবাইট” ধরা পড়ে। সঠিক সীমার জন্য ছোট একক ব্যবহার করুন: -size -1024k।
কোন ফাইল ডিস্কের জায়গা দখল করছে
find-এর সঙ্গে ls ও sort জুড়লে সবচেয়ে বড় ফাইলগুলো দেখা যায়:
find /var -type f -size +50M -exec ls -lh {} + 2>/dev/null | sort -k5 -rh | head
-rw-r----- 1 syslog adm 1.2G Oct 14 09:12 /var/log/syslog.1
-rw-r--r-- 1 root root 412M Oct 10 03:00 /var/backups/db.sql.gz
-rw-r----- 1 root adm 96M Oct 14 09:15 /var/log/nginx/access.log
পুরো ডিরেক্টরির আকার জানতে du -sh সুবিধাজনক, আর কোনো গভীরে একটিমাত্র বিশাল ফাইল জায়গা খেয়ে থাকলে find ভালো।
তারিখ দিয়ে খোঁজা: -mtime, -mmin, -newer
প্রতিটি ফাইলের তিনটি সময়-চিহ্ন থাকে, find প্রতিটি দিয়েই ছাঁকতে পারে:
| শর্ত | চিহ্ন | একক |
|---|---|---|
-mtime / -mmin | বিষয়বস্তু বদলানো | দিন / মিনিট |
-atime / -amin | সর্বশেষ পড়া | দিন / মিনিট |
-ctime / -cmin | মেটাডেটা বদলানো (অনুমতি, মালিক, নাম) | দিন / মিনিট |
চিহ্নগুলো আকারের মতোই কাজ করে: -mtime -7 — 7 দিনের কম আগে বদলানো, -mtime +30 — 30 দিনের বেশি আগে বদলানো।
# গত এক সপ্তাহে বদলানো
find ~/projects -type f -mtime -7
# 30 দিনের পুরনো লগ
find /var/log -type f -name '*.log' -mtime +30
# গত 15 মিনিটে বদলানো
find /etc -type f -mmin -15
দিন গোনা হয় পূর্ণ 24 ঘণ্টার ব্লকে, ভগ্নাংশ বাদ যায়। এ কারণে -mtime +1 24 ঘণ্টার নয়, 48 ঘণ্টার বেশি পুরনো ফাইল খোঁজে — এটি একটি সাধারণ ফাঁদ। সূক্ষ্মতা দরকার হলে মিনিট ব্যবহার করুন: -mmin +1440।
অন্য ফাইল বা তারিখের চেয়ে নতুন ফাইল
# deploy.lock বদলানোর পরে বদলানো ফাইল
find . -type f -newer deploy.lock
# নির্দিষ্ট তারিখের পরে বদলানো ফাইল (GNU find)
find . -type f -newermt '2026-10-01'
# তারিখের একটি সীমার মধ্যে
find . -type f -newermt '2026-10-01' ! -newermt '2026-10-08'
মালিক ও অনুমতি দিয়ে খোঁজা
# alice-এর ফাইল
find /home -user alice
# যেসব ফাইলের মালিক আর নেই (ব্যবহারকারী মুছে ফেলার পরে)
find / -nouser 2>/dev/null
# অনুমতি ঠিক 777
find /var/www -type f -perm 777
# যেসব ফাইলে সবাই লিখতে পারে
find /var/www -perm -o=w
# SUID বিট থাকা ফাইল — নিরাপত্তা অডিটে কাজে লাগে
find / -perm -4000 -type f 2>/dev/null
-perm-এর তিনটি রূপ আছে: চিহ্ন ছাড়া — অনুমতি হুবহু মেলে, - দিয়ে — উল্লিখিত সব বিট অন্তত থাকতে হবে, / দিয়ে — অন্তত একটি বিট থাকলেই চলে।
শর্তের যুক্তি: এবং, অথবা, না
শর্তগুলো ডিফল্টভাবে “এবং” দিয়ে যুক্ত হয়। “অথবা”-এর জন্য -o, আর অস্বীকারের জন্য ! বা -not। গ্রুপ করা হয় বন্ধনী দিয়ে, যেগুলো shell থেকে এস্কেপ করতে হয়:
# jpg বা png ছবি
find . -type f \( -name '*.jpg' -o -name '*.png' \)
# .tmp ফাইল ছাড়া সব
find . -type f ! -name '*.tmp'
বন্ধনী না থাকলে -type f শুধু “অথবা”-জোড়ার প্রথম শর্তে লাগবে, আর ফলাফলে *.png নামের ডিরেক্টরিও ঢুকে পড়বে। \( ও \)-এর চারপাশে ফাঁকা জায়গা অবশ্যই থাকতে হবে।
খোঁজার গভীরতা: -maxdepth ও -mindepth
# শুধু বর্তমান ডিরেক্টরিতে, ভেতরে নয়
find . -maxdepth 1 -type f -name '*.sh'
# দ্বিতীয় স্তর থেকে শুরু করে
find . -mindepth 2 -name '*.md'
# অন্য ফাইল সিস্টেমে না যাওয়া
find / -xdev -type f -size +1G
-maxdepth পথের ঠিক পরে, বাকি শর্তের আগে বসান — নইলে GNU find সতর্কবার্তা দেবে। /-এ খোঁজার সময় -xdev কাজে লাগে: find /proc, নেটওয়ার্ক ও সংযুক্ত ডিস্কে ঢুকবে না।
খোঁজা ফাইলের ওপর কাজ: -exec, -delete, xargs
-exec: প্রতিটি ফাইলের জন্য কমান্ড চালানো
{}-এর জায়গায় find ফাইলের পাথ বসায়। কমান্ড শেষ হয় \; বা + দিয়ে:
# প্রতি ফাইলের জন্য আলাদা চালানো
find . -name '*.sh' -exec chmod +x {} \;
# সব ফাইল এক তালিকায় — দ্রুত
find . -name '*.log' -exec gzip {} +
# প্রতি ফাইলে নিশ্চিত করে নেওয়া
find . -name '*.bak' -ok rm {} \;
+-এর বিকল্প পাথগুলো ভাগে ভাগে জড়ো করে কমান্ডটি অনেক কম বার চালায়, তাই হাজার ফাইলে এটি কয়েক গুণ দ্রুত। \; দরকার হয় যখন কমান্ড একবারে একটি ফাইল নেয়, অথবা {} শেষে না থাকে।
-delete: পাওয়া ফাইল মুছে ফেলা
# আগে দেখে নিন কী মোছা পড়বে
find /tmp/build -type f -name '*.o' -mtime +7
# তারপর মুছুন
find /tmp/build -type f -name '*.o' -mtime +7 -delete
সবসময় -delete ছাড়া চালিয়ে তালিকা যাচাই করুন। আর -delete সবশেষে রাখুন: find শর্তগুলো বাঁ থেকে ডান দিকে কার্যকর করে, তাই find . -delete -name '*.o' পুরো ডিরেক্টরি মুছে ফেলবে, নাম যাচাই করার আগেই।
find ও xargs
ফাইলের তালিকা xargs দিয়ে অন্য প্রোগ্রামে পাঠানো একটি ক্লাসিক জোড়া। স্পেস থাকা নামে ভাঙা এড়াতে শূন্য বাইটকে বিভাজক হিসেবে ব্যবহার করুন:
find . -type f -name '*.txt' -print0 | xargs -0 wc -l
xargs-এর -P ফ্ল্যাগ একসঙ্গে একাধিক প্রসেস সমান্তরালে (parallel) চালায়:
find ./images -name '*.png' -print0 | xargs -0 -P 4 -n 10 optipng
find ও grep: ফাইলের ভেতরে টেক্সট খোঁজা
find ফাইল খোঁজে, তাদের বিষয়বস্তু নয়। বাছাই করা ফাইলের ভেতরে লাইন খুঁজতে সেগুলো grep-কে দিন:
# কোন কনফিগে listen 8080 আছে
find /etc/nginx -type f -name '*.conf' -exec grep -Hn 'listen 8080' {} +
/etc/nginx/sites-enabled/app.conf:4: listen 8080;
-H ফাইলের নাম প্রিন্ট করে, -n লাইন নম্বর, আর grep -l শুধু মিলে যাওয়া ফাইলের নাম দেখায়। শুধু এক্সটেনশনে ছাঁকতে হলে grep নিজেই যথেষ্ট: grep -rn --include='*.conf' 'listen 8080' /etc/nginx।
নিজের ফরম্যাটে আউটপুট: -printf
GNU find শুধু পাথ নয়, অন্য তথ্যও প্রিন্ট করতে পারে। যেমন আকার, তারিখ ও নাম:
find . -maxdepth 1 -type f -printf '%s\t%TY-%Tm-%Td\t%p\n' | sort -n
এখানে %s — বাইটে আকার, %T... — পরিবর্তনের তারিখের আলাদা অংশ, %p — পাথ। স্ক্রিপ্টের জন্য এটি সুবিধাজনক: ls-এর আউটপুট ভাঙতে হয় না।
প্রতিদিনের কাজের জন্য find-এর সংক্ষিপ্ত তালিকা
| কাজ | কমান্ড |
|---|---|
| নাম দিয়ে ফাইল খোঁজা | find / -name 'file.txt' 2>/dev/null |
| ছোট-বড় হাতের অক্ষর উপেক্ষা | find . -iname '*.jpg' |
| শুধু ডিরেক্টরি | find . -type d -name 'cache' |
| 1 GB-এর বড় ফাইল | find / -xdev -type f -size +1G |
| গত এক দিনে বদলানো | find . -type f -mtime -1 |
| গত এক ঘণ্টায় বদলানো | find . -type f -mmin -60 |
| 30 দিনের পুরনো লগ মোছা | find /var/log/app -name '*.log' -mtime +30 -delete |
| খালি ডিরেক্টরি | find . -type d -empty |
| সব ডিরেক্টরির অনুমতি বদলানো | find . -type d -exec chmod 755 {} + |
| ফাইলের ভেতরে টেক্সট | find . -name '*.py' -exec grep -l 'TODO' {} + |
| ফাইল গোনা | find . -type f | wc -l |
সাধারণ ভুলসমূহ
- উদ্ধৃতি ছাড়া প্যাটার্ন।
find . -name *.logভেঙে যায়, যদি বর্তমান ডিরেক্টরিতে একটিও.logফাইল থাকে। লিখুন'*.log'। - Permission denied-এর বন্যা।
2>/dev/nullযোগ করুন, অথবা পুরো ডিস্ক সত্যিই দরকার হলেsudoদিয়ে চালান। -deleteভুল জায়গায়। এটি সবসময় শেষে থাকে, আর তার আগে একটি মুছে না ফেলা যাচাই-চালনা দিন।- পাইপলাইনে স্পেসওয়ালা নাম।
find ... | xargs rm“My File.txt”-কে দুটি আর্গুমেন্টে ভাঙে।-print0ওxargs -0বা-execব্যবহার করুন। -mtime-এর কাছে সঠিক দিন আশা। সূক্ষ্ম সময়সীমার জন্য-mminবা-newermtনিন।
সারসংক্ষেপ
find ফাইল সিস্টেম খোঁজার একটি বহুমুখী টুল: পথ, এরপর নাম, ধরন, আকার, তারিখ ও অনুমতির শর্ত, তারপর কাজ। পাঁচটি স্তম্ভ আয়ত্ত করুন — -name, -type, -size, -mtime ও -exec ... + — তাহলে বেশিরভাগ কাজ এক লাইনেই হয়ে যাবে। উপরের find linux উদাহরণগুলো নিজের টার্মিনালে একবার চালিয়ে দেখুন, আর find-কে grep, sed ও awk-এর সঙ্গে জুড়ে কাজ করার কৌশল লিনাক্স কোর্সের টেক্সট প্রসেসিং লেকচারে হাতে-কলমে শেখানো হয়।
সাধারণ প্রশ্ন
find ও locate-এর পার্থক্য কী?
locate আগে থেকে তৈরি করা নামের ডেটাবেসে খোঁজে, তাই খুব দ্রুত চলে, কিন্তু updatedb শেষ চালানোর পরে তৈরি ফাইল দেখায় না। find ডিস্ক সরাসরি ঘুরে দেখে এবং আকার, তারিখ ও অনুমতি দিয়ে ছাঁকতে পারে।
নামের বদলে ফাইলের বিষয়বস্তু দিয়ে কীভাবে খুঁজবেন?
find নিজে বিষয়বস্তু পড়ে না। ব্যবহার করুন grep -rn 'টেক্সট' /পথ, অথবা find . -name '*.conf' -exec grep -l 'টেক্সট' {} +।
পুরো ডিস্কের রুট থেকে find কেন ধীর চলে?
এটি সব ডিরেক্টরি ঘুরে দেখে, যার মধ্যে /proc, /sys ও সংযুক্ত ডিস্কও আছে। খোঁজা একটি নির্দিষ্ট ডিরেক্টরিতে সীমিত করুন, -xdev ও -maxdepth যোগ করুন, অথবা -prune দিয়ে অপ্রয়োজনীয় অংশ বাদ দিন।
find-এর ফলাফল তারিখ অনুযায়ী সাজানো যায়?
হ্যাঁ: find . -type f -printf '%T@ %p\n' | sort -n পুরনো থেকে নতুন ক্রমে দেখাবে, যেখানে %T@ — পরিবর্তনের সময় ইপক থেকে সেকেন্ডে।
খালি ডিরেক্টরি কীভাবে খুঁজে মুছবেন?
find . -type d -empty -delete সব খালি ডিরেক্টরি মুছে দেবে, যেগুলো ভেতরের ফাইল মোছার পরে খালি হয়েছে সেগুলোও। আগে -delete ছাড়া চালিয়ে তালিকা যাচাই করুন।
“Linux: с нуля до уверенного администрирования” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।
কোর্সে যান