find در لینوکس: پیدا کردن فایل بر اساس نام، زمان و نوع
کار با find برای نام، اندازه، زمان ویرایش، -exec، حذف امن و تفاوت با grep و locate در لینوکس.
Founder & product engineer

grep داخل محتوا میگردد؛ find روی درخت فایلسیستم راه میرود و بر اساس نام، نوع، مجوز، اندازه و زمان انتخاب میکند. وقتی میپرسید «کدام فایلهای لاگ از هفت روز پیش بزرگتر از ۱۰۰ مگابایتاند؟» ابزار درست find است نه جستوجوی متن.
قدرت find در ترکیب آزمونها و عملهاست: پیدا کن، چاپ کن، یا با احتیاط روی هر نتیجه فرمانی اجرا کن. خطرش هم همانجاست — -delete یا -exec rm روی مسیر اشتباه خسارت واقعی میسازد.

پاسخ کوتاه
شروع از یک ریشهٔ مشخص: `find /var/log -name '*.log' -type f`. زمان: `-mtime -7` برای تغییر در ۷ روز اخیر. اندازه: `-size +100M`. اجرای فرمان: ترجیحاً `-print0` با `xargs -0` یا `-exec ... {} +`. قبل از حذف، اول فقط چاپ کنید. برای جستوجوی تعاملی نام روی دسکتاپ، ابزارهای جدیدتر مثل fd سریعترند؛ روی سرور، find استاندارد قابلاعتماد است.
اول مسیر را تنگ کنید، بعد شرط؛ find از / بدون فیلتر هم کند است هم پرحرف.
شکل پایه
bash
find . -name 'config.yaml' find . -iname 'readme*' find /etc -type f -name '*.conf' 2>/dev/null | head
-name به کوچک/بزرگحساس است؛ -iname نیست. الگو glob است نه regex مگر -regex. نقلقول دور الگو مهم است تا شل زودتر * را باز نکند.
نوع، عمق و هرس مسیر
bash
find . -type d -name 'node_modules' find . -type f -name '*.js' -not -path '*/node_modules/*' find . -maxdepth 2 -type f find /var -path '/var/lib/docker/*' -prune -o -name '*.log' -print
-type f فایل عادی، d پوشه، l لینک نمادین. -maxdepth جلوی فرورفتن بینهایت را میگیرد. -prune برای رد کردن زیردرختهای گران (مثل docker volumes) حیاتی است.
زمان و اندازه
bash
find /var/log -type f -mtime +14 find /var/log -type f -mtime -1 find /tmp -type f -mmin -30 find /var/log -type f -size +100M -ls find . -type f -empty
-mtime +14 یعنی آخرین تغییر محتوا بیش از ۱۴ روز پیش؛ -mtime -1 یعنی در ۲۴ ساعت اخیر. واحد روز برای mtime و دقیقه برای mmin را قاطی نکنید. -size +100M بزرگتر از ۱۰۰ مگابایت.
مجوز و مالک
bash
find /var/www -type f -perm -o=w find /home -type f -user ubuntu -name '*.pem' 2>/dev/null find . -type f -perm 777
یافتن فایل world-writable یا کلید خصوصی رهاشده بخشی از سختسازی سبک است. خروجی را قبل از هر اقدام جمعی مرور کنید.
عمل روی نتایج: print0 و xargs
bash
find . -type f -name '*.log' -print0 | xargs -0 ls -lh find . -type f -name '*.tmp' -print0 | xargs -0 rm -f
نام فایل با فاصله یا خط جدید بدون -print0 / -0 میشکند. عادت کنید همیشه حالت null-delimited را برای اتوماسیون به کار ببرید.
-exec و تفاوت {} \; با {} +
bash
find . -type f -name '*.py' -exec grep -H 'TODO' {} + find . -name '*.bak' -exec rm -i {} \;
{} + چند فایل را به یک اجرای فرمان میدهد (کاراتر)؛ \; برای هر فایل جدا اجرا میکند. rm -i برای یادگیری خوب است؛ در cron تعاملی نیست — آنجا اول dry-run چاپ کنید.
حذف امن: الگوی دو مرحلهای
- find با همان شرط فقط -print یا -ls.
- مرور لیست؛ اگر درست بود، همان شرط با -delete یا xargs rm.
- روی production، بکاپ/snapshot را قبل از پاکسازی دستهای جدی بگیرید.
bash
find /var/log/myapp -type f -name '*.log' -mtime +30 -print # پس از تأیید: find /var/log/myapp -type f -name '*.log' -mtime +30 -delete
-delete خودش را به سمت راست آزمونها حساس میداند؛ ترتیب عبارتها را از مستند نسخه بخوانید. مسیر ریشه را دوبار چک کنید.
find در برابر locate و fd
| ابزار | نقطهٔ قوت | محدودیت |
|---|---|---|
| find | شرط زنده روی متادیتا، همهجا | میتواند روی درخت بزرگ کند باشد |
| locate/mlocate | جستوجوی نام از DB سریع | DB ممکن است کهنه باشد؛ نه همهٔ شرطها |
| fd | UX مدرن، سرعت، ignore | ممکن است نصب نباشد |
locate بعد از updatedb میدرخشد؛ برای فایل تازهساختهشده همان لحظه find مطمئنتر است.
ترکیب با grep
bash
find src -type f -name '*.go' -print0 | xargs -0 grep -n 'ListenAndServe' find /etc -type f -name '*.conf' -exec grep -l 'Listen ' {} +
این الگوی کلاسیک «اول فایلها را با متا محدود کن، بعد محتوا را بجو» است و از grep -r بیقید روی کل دیسک بهتر است.
اشتباههای رایج
- شروع از / بدون prune و پر شدن بار IO.
- فراموش نقلقول -name '*.log' و انبساط شل.
- xargs بدون -0 روی نامهای فاصلهدار.
- -exec rm بدون چاپ قبلی.
- اشتباه گرفتن -mtime +1 با «دیروز» به معنای تقویمی سست.
سناریو: پاکسازی دیسک قبل از پر شدن
وقتی df هشدار میدهد، بهجای حذف کور:
bash
df -h find /var/log -type f -size +50M -mtime +7 -ls 2>/dev/null | head find /tmp -type f -mtime +3 -ls 2>/dev/null | head
بزرگان را پیدا کنید، به صاحب سرویس بگویید، سیاست retention را درست کنید — نه اینکه هر شب همهٔ /var را جارو کنید.
find و لینک نمادین
bash
find . -type l find -L . -type f -name '*.conf'
بهطور پیشفرض find وارد لینک پوشه نمیشود مگر سیاست -follow/-L. روی درختهایی با لینک حلقوی مراقب باشید.
زمان دسترسی در برابر تغییر
-atime به دسترسی مربوط است و روی بعضی فایلسیستمها با noatime بیمعنا یا گمراهکننده میشود. برای پاکسازی لاگ معمولاً -mtime یا -ctime عملیتر است. مستند mount گزینهها را ببینید.
خروجی ماشینخوان برای اسکریپت
bash
find /srv/data -type f -name '*.csv' -printf '%p\t%s\t%T@\n' | head
-printf در GNU find کنترل قالب میدهد؛ برای قابلحمل بودن POSIXمحض، به -print و پردازش بعدی تکیه کنید و وابستگی GNU را در README بنویسید.
چه زمانی find نه؟
- جستوجوی محتوای متن: grep/rg.
- ایندکس نام روی دسکتاپ روزمره: ابزار UI یا fd.
- لیست بستهٔ نصبشده: apt/dpkg/rpm نه find روی /usr.
find و بکاپ قبل از پاکسازی
حتی وقتی لیست را مرور کردهاید، روی دادهٔ کاربر یک کپی یا snapshot بگیرید. دستور حذف دستهای برگشتناپذیر است؛ هزینهٔ بکاپ کوتاه معمولاً کمتر از بازیابی اضطراری است.
در تیم، اسکریپت پاکسازی را با متغیر DRY_RUN بنویسید که پیشفرضش فقط چاپ باشد و حذف فقط با پرچم صریح فعال شود.
bash
DRY_RUN=1 find /var/tmp/myapp -type f -mtime +14 -print # حذف فقط وقتی DRY_RUN=0 و تأیید انسانی
مجوز کافی و خطای stderr
find روی مسیر بدون اجرا/خواندن پوشه خطا میدهد. در اسکریپتها اغلب stderr را جدا لاگ کنید تا با لیست نتایج قاطی نشود. خاموش کردن کامل خطاها عیبیابی را سخت میکند.
bash
find /home -name '*.pem' 2>/tmp/find.err | tee /tmp/find.out | head wc -l /tmp/find.err /tmp/find.out
تفاوت -mtime و -daystart
در GNU find گزینههایی مثل -daystart تفسیر «روز» را به نیمهشب نزدیک میکنند. اگر گزارش انطباقی مینویسید، رفتار پیشفرض را در مستند نسخه بخوانید و در تست با فایل touchشده با زمان مشخص تأیید کنید.
find برای موجودی نرمافزار سبک
گاهی میخواهید بدانید کجا باینری یا فایل پیکربندی رها شده بدون بستهٔ رسمی. find جایگزین dpkg/rpm نیست ولی برای مسیرهای سفارشی مثل /opt و /usr/local مفید است:
bash
find /opt /usr/local -type f -executable 2>/dev/null | head find /etc -type f -name '*.bak' 2>/dev/null | head
خروجی را با فهرست بسته مقایسه کنید تا فایل یتیم بعد از حذف سرویس پیدا شود. این کار بخشی از بهداشت سرور است که معمولاً عقب میافتد تا دیسک پر شود.
زمانبندی چنین جارویی را با ionice/nice در ساعات کمبار انجام دهید تا روی دیسک تولید فشار نیاورید.
خلاصه
find راه رفتن هدفمند روی درخت فایل است: نام، نوع، زمان، اندازه، مجوز، سپس چاپ یا عمل. مسیر را محدود کنید، null-delimited کار کنید، حذف را دو مرحلهای کنید. با grep برای محتوا ترکیبش کنید و با locate/fd برای سرعت نام آشنا باشید.
سوالات متداول
چرا find چیزی برنمیگرداند؟
مجوز خواندن پوشه، مسیر غلط، یا glob بدون نقلقول. با ls روی همان ریشه شروع کنید.
تفاوت -delete و -exec rm چیست؟
-delete توکار find است؛ rm انعطاف پرچمهای rm را دارد. هر دو خطرناکاند اگر شرط اشتباه باشد.
چطور فقط فایلهای تغییر یافته امروز را ببینم؟
`find . -type f -mtime -1` نقطهٔ شروع است؛ برای دقیقتر، -newermt با تاریخ GNU find.
منابع و مراجع
- find(1) — Linux manual page: https://man7.org/linux/man-pages/man1/find.1.html
- GNU Findutils Manual: https://www.gnu.org/software/findutils/manual/html_mono/find.html
- xargs(1): https://man7.org/linux/man-pages/man1/xargs.1.html
- locate(1) (mlocate/plocate family): https://man7.org/linux/man-pages/man1/locate.1.html
Author
Soheil Ebrahimpour is the founder of FutureForge. He works on product design, architecture, and getting custom software into production.
Related notes
If you are unsure about architecture or the build path, we can talk about the project.
Describe the problem and the constraints. If there is a fit, we will schedule a conversation.




