رفتن به محتوا
LoopX

پیدا کردن فایل‌ها

توی این درس یاد می‌گیری وقتی نمی‌دانی فایلی کجاست یا می‌خواهی همه‌ی فایل‌هایی با یک ویژگی را پیدا کنی، از find استفاده کنی: بر اساس اسم (-name)، نوع (-type)، حجم (-size) و زمان تغییر (-mtime). شرط‌ها را با هم ترکیب می‌کنی، روی نتیجه‌ها دستور اجرا می‌کنی (-exec و -delete) و می‌فهمی چرا باید همیشه اول بدون حذف امتحان کنی. با locate هم که از یک پایگاه داده‌ی از پیش ساخته‌شده می‌خواند، جستجوی بسیار سریع می‌کنی. تمرین: همه‌ی فایل‌های بزرگ‌تر از ۵۰ مگابایت پوشه‌ی خانه را پیدا می‌کنی.

مسئله: دیسک پر شده، کدام فایل‌ها؟

Section titled “مسئله: دیسک پر شده، کدام فایل‌ها؟”

یک سرور ناگهان هشدار «دیسک ۹۵٪ پر است» می‌دهد. چه چیزی جا گرفته؟ می‌خواهی همه‌ی فایل‌های بزرگ‌تر از ۱۰۰ مگابایت را فهرست کنی. یا باید فایل‌های .tmp قدیمی‌تر از یک هفته را پاک کنی. یا فایلی که «یک جایی» بود را پیدا کنی. بدون find باید دستی پوشه‌ها را بگردی؛ با find یک خط است.

تشبیه: کارآگاه با فهرست مشخصات

Section titled “تشبیه: کارآگاه با فهرست مشخصات”

find مثل کارآگاهی است که کل ساختمان را (از پوشه‌ای که می‌دهی به پایین) خانه‌به‌خانه می‌گردد و برای هر فایل می‌پرسد «با این مشخصات می‌خواند؟» (اسم، نوع، حجم، زمان). locate مثل یک دفتر فهرست از پیش نوشته‌شده است: لحظه‌ای جواب می‌دهد ولی فهرستش ممکن است کهنه باشد.

find در لحظه‌ی اجرا پوشه‌ها را می‌گردد (دقیق و تازه ولی کندتر)؛ locate از یک پایگاه داده‌ی ساخته‌شده می‌خواند (سریع ولی ممکن است کهنه باشد و فقط اسم را جستجو می‌کند).

برای تمرین یک درخت نمونه با فایل‌های متنوع (اسم، نوع، حجم، زمان) می‌سازیم:

Terminal window
mkdir -p lab/{logs,docs,src/utils,tmp}
echo "info" > lab/logs/app.log
echo "error" > lab/logs/error.log
echo "old" > lab/logs/old.log.1
echo "readme" > lab/docs/README.md
echo "NOTES" > lab/docs/Notes.TXT
echo "print(1)" > lab/src/main.py
echo "x=2" > lab/src/utils/helper.py
echo "cache" > lab/tmp/a.tmp
echo "cache2" > lab/tmp/b.tmp
ln -s ../docs/README.md lab/src/readme-link
truncate -s 60M lab/tmp/big.img # فایل ۶۰ مگابایتی (sparse: فضای واقعی نمی‌گیرد)
truncate -s 5K lab/docs/medium.bin
# تنظیم زمان‌ها: امروز، ۲ روز پیش، ۱۰ روز پیش
touch -d "2 days ago" lab/logs/error.log
touch -d "10 days ago" lab/logs/old.log.1 lab/tmp/a.tmp
echo "ساخته شد"
خروجی
ساخته شد

(truncate -s یک فایل با حجم ظاهری دلخواه می‌سازد؛ و touch -d زمان تغییر را عوض می‌کند. این دو فقط برای ساختن مثال‌اند.)

مثال ۱: پیدا کردن با اسم، -name

Section titled “مثال ۱: پیدا کردن با اسم، -name”

ساختار کلی: find از-کجا شرط‌ها.... اولین argument مسیر شروع است و find همه‌ی زیرپوشه‌ها را می‌گردد:

Terminal window
find lab -name "*.log" | sort
echo "--- بدون حساسیت به حروف (-iname):"
find lab -iname "*.txt" | sort
echo "--- با -name حساس به حروف:"
find lab -name "*.txt" | sort
خروجی
lab/logs/app.log
lab/logs/error.log
--- بدون حساسیت به حروف (-iname):
lab/docs/Notes.TXT
--- با -name حساس به حروف:

الگو ("*.log") مثل wildcard است ولی خود find آن را تفسیر می‌کند، پس باید quote بگذاری (توضیح در «پشت پرده»). -name به حروف کوچک/بزرگ حساس است: Notes.TXT با *.txt پیدا نشد ولی با -iname پیدا می‌شود. فقط اسم (نه مسیر) با الگو مقایسه می‌شود؛ برای مسیر کامل -path "*/src/*".

Terminal window
echo "--- فقط پوشه‌ها (-type d):"
find lab -type d | sort
echo "--- فقط فایل‌های معمولی (-type f) با پسوند py:"
find lab -type f -name "*.py" | sort
echo "--- لینک‌های نمادین (-type l):"
find lab -type l
خروجی
--- فقط پوشه‌ها (-type d):
lab
lab/docs
lab/logs
lab/src
lab/src/utils
lab/tmp
--- فقط فایل‌های معمولی (-type f) با پسوند py:
lab/src/main.py
lab/src/utils/helper.py
--- لینک‌های نمادین (-type l):
lab/src/readme-link

-type f فایل، d پوشه، l symlink. ترکیبشان با -name خیلی رایج است: «فایل‌های .py» (نه پوشه‌ای که اسمش .py است).

⚡ بررسی سریع

چرا الگوی -name را باید در quote گذاشت؟

Terminal window
echo "--- بزرگ‌تر از 50 مگابایت (+50M):"
find lab -type f -size +50M
echo "--- بزرگ‌تر از 1 کیلوبایت و کوچک‌تر از 1 مگابایت:"
find lab -type f -size +1k -size -1M
echo "--- فایل‌های خالی یا کوچک‌تر از یک بایت (-empty):"
find lab -type f -empty | head -3
خروجی
--- بزرگ‌تر از 50 مگابایت (+50M):
lab/tmp/big.img
--- بزرگ‌تر از 1 کیلوبایت و کوچک‌تر از 1 مگابایت:
--- فایل‌های خالی یا کوچک‌تر از یک بایت (-empty):

واحدها: c بایت، k کیلوبایت، M مگابایت، G گیگابایت. علامت‌ها: +N بزرگ‌تر از N، -N کوچک‌تر از N، و بدون علامت دقیقاً N. (نکته: find حجم را به واحد گرد می‌کند و بالا می‌برد؛ برای دقیق‌تر بودن از c استفاده کن.) پیدا کردن فایل‌های حجیم در تمام سیستم: find / -type f -size +100M 2>/dev/null (بعدش 2>/dev/null را توضیح می‌دهم).

مثال ۴: بر اساس زمان، -mtime و -mmin

Section titled “مثال ۴: بر اساس زمان، -mtime و -mmin”
Terminal window
echo "--- تغییرکرده در 24 ساعت اخیر (-mtime -1):"
find lab -type f -mtime -1 | sort
echo "--- قدیمی‌تر از 7 روز (+7):"
find lab -type f -mtime +7 | sort
echo "--- در 5 دقیقه‌ی اخیر (-mmin -5):"
find lab -type f -mmin -5 -name "*.py" | sort
echo "--- جدیدتر از یک فایل دیگر (-newer):"
find lab -type f -newer lab/logs/error.log | sort | head -3
خروجی
--- تغییرکرده در 24 ساعت اخیر (-mtime -1):
lab/docs/Notes.TXT
lab/docs/README.md
lab/docs/medium.bin
lab/logs/app.log
lab/src/main.py
lab/src/utils/helper.py
lab/tmp/b.tmp
lab/tmp/big.img
--- قدیمی‌تر از 7 روز (+7):
lab/logs/old.log.1
lab/tmp/a.tmp
--- در 5 دقیقه‌ی اخیر (-mmin -5):
lab/src/main.py
lab/src/utils/helper.py
--- جدیدتر از یک فایل دیگر (-newer):
lab/docs/Notes.TXT
lab/docs/README.md
lab/docs/medium.bin

-mtime n بر حسب روز (۲۴ ساعت) و -mmin n بر حسب دقیقه. باز هم -n = «کمتر از» و +n = «بیشتر از». یک نکته‌ی گیج‌کننده: -mtime +1 یعنی «بیش از ۲ روز» (چون کسر روز دور ریخته می‌شود). برای زمان آخرین دسترسی -atime و تغییر وضعیت (دسترسی/مالک) -ctime. -newer فایل یعنی «جدیدتر از آن فایل».

مثال ۵: ترکیب شرط‌ها، -and، -or، !

Section titled “مثال ۵: ترکیب شرط‌ها، -and، -or، !”

شرط‌های پشت سر هم به‌طور پیش‌فرض با «و» ترکیب می‌شوند. برای «یا» از -o و برای دسته‌بندی از پرانتز (با بک‌اسلش) استفاده کن:

Terminal window
echo "--- فایل‌های log یا tmp:"
find lab -type f \( -name "*.log*" -o -name "*.tmp" \) | sort
echo "--- فایل‌های py که utils نیستند (با ! -path):"
find lab -type f -name "*.py" ! -path "*/utils/*"
echo "--- فایل‌های tmp قدیمی (و):"
find lab -type f -name "*.tmp" -mtime +7
خروجی
--- فایل‌های log یا tmp:
lab/logs/app.log
lab/logs/error.log
lab/logs/old.log.1
lab/tmp/a.tmp
lab/tmp/b.tmp
--- فایل‌های py که utils نیستند (با ! -path):
lab/src/main.py
--- فایل‌های tmp قدیمی (و):
lab/tmp/a.tmp

! (یا -not) شرط بعدی را معکوس می‌کند. پرانتزها را باید با \( و \) بنویسی تا shell تفسیرشان نکند، و دور آن‌ها فاصله بگذاری.

مثال ۶: محدود کردن عمق، -maxdepth

Section titled “مثال ۶: محدود کردن عمق، -maxdepth”
Terminal window
echo "--- فقط همین سطح (-maxdepth 1):"
find lab -maxdepth 1 | sort
echo "--- تا دو سطح:"
find lab -maxdepth 2 -type d | sort
خروجی
--- فقط همین سطح (-maxdepth 1):
lab
lab/docs
lab/logs
lab/src
lab/tmp
--- تا دو سطح:
lab
lab/docs
lab/logs
lab/src
lab/src/utils
lab/tmp

-maxdepth N عمق جست‌وجو را محدود می‌کند (۱ یعنی فقط داخل همین پوشه). -mindepth 1 خودِ پوشه‌ی شروع را از نتیجه حذف می‌کند. بیشتر وقتی می‌خواهی فقط محتوای یک سطح را ببینی یا جلوی جستجوی طولانی را بگیری.

مثال ۷: اجرای دستور روی نتیجه‌ها، -exec و -delete

Section titled “مثال ۷: اجرای دستور روی نتیجه‌ها، -exec و -delete”

عمل پیش‌فرض -print است (اسم را چاپ کن). به‌جایش می‌توانی دستور اجرا کنی: -exec دستور {} \; برای هر فایل، با {} به‌جای اسم و \; پایان دستور:

Terminal window
echo "--- حجم هر فایل log:"
find lab -name "*.log*" -type f -exec ls -l {} \; | awk '{print $5, $9}' | sort -k2
echo "--- شمارش خط‌ها با یک بار اجرا (+ به‌جای \\;):"
find lab -name "*.py" -type f -exec wc -l {} +
echo "--- نمایش مثل ls -l (-ls):"
find lab/logs -type f -ls | awk '{print $3, $5, $11}' | sort -k3
خروجی
--- حجم هر فایل log:
5 lab/logs/app.log
6 lab/logs/error.log
4 lab/logs/old.log.1
--- شمارش خط‌ها با یک بار اجرا (+ به‌جای \;):
1 lab/src/main.py
1 lab/src/utils/helper.py
2 total
--- نمایش مثل ls -l (-ls):
-rw-r--r-- ali lab/logs/app.log
-rw-r--r-- ali lab/logs/error.log
-rw-r--r-- ali lab/logs/old.log.1

با \; دستور برای هر فایل جدا اجرا می‌شود؛ با + نام‌ها دسته‌ای به یک اجرا داده می‌شوند (سریع‌تر برای دستورهایی مثل wc، grep، rm که چند argument می‌پذیرند). و برای حذف:

Terminal window
echo "--- پیش‌نمایش (بدون -delete):"
find lab/tmp -name "*.tmp" -mtime +7
echo "--- حالا واقعاً حذف:"
find lab/tmp -name "*.tmp" -mtime +7 -delete
echo "--- باقی‌مانده در tmp:"
ls lab/tmp
خروجی
--- پیش‌نمایش (بدون -delete):
lab/tmp/a.tmp
--- حالا واقعاً حذف:
--- باقی‌مانده در tmp:
b.tmp
big.img

قاعده‌ی طلایی: اول همان دستور را بدون -delete (فقط -print) اجرا کن و خروجی را بخوان؛ فقط بعد -delete را اضافه کن. و -delete را آخرین شرط بگذار (اگر اول بگذاری، شرط‌های بعدی را اعمال نمی‌کند و همه‌چیز را پاک می‌کند).

مثال ۸: خطاهای دسترسی و 2>/dev/null

Section titled “مثال ۸: خطاهای دسترسی و 2>/dev/null”

وقتی از / شروع می‌کنی، به پوشه‌هایی می‌رسی که اجازه‌ی ورود نداری و برای هر کدام یک خطا می‌دهد:

Terminal window
echo "--- بدون سرکوب خطا (شمارش خطوط):"
find / -name "hostname" 2>&1 | wc -l
echo "--- نتیجه‌ی اصلی (stderr را دور بریز):"
find / -name "hostname" -type f 2>/dev/null | sort
خروجی
--- بدون سرکوب خطا (شمارش خطوط):
214
--- نتیجه‌ی اصلی (stderr را دور بریز):
/etc/hostname
/proc/sys/kernel/hostname
/usr/bin/hostname

خطاها روی stderr (جریان ۲) می‌روند و 2>/dev/null آن‌ها را دور می‌ریزد (در درس «redirect» کامل). نتیجه‌ها روی stdout هستند و دست نخورده می‌مانند. sudo find ... هم گزینه‌ی دیگر است ولی لازم نیست بی‌دلیل root باشی.

مثال ۹: بر اساس دسترسی و مالک

Section titled “مثال ۹: بر اساس دسترسی و مالک”
Terminal window
echo "--- برنامه‌هایی با setuid (دسترسی ویژه، درس‌های بعد):"
find /usr/bin -perm -4000 2>/dev/null | sort
echo "--- فایل‌های متعلق به کاربر ali در پوشه‌ی lab:"
find lab -user ali -type f | head -3
خروجی
--- برنامه‌هایی با setuid (دسترسی ویژه، درس‌های بعد):
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/mount
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/su
/usr/bin/sudo
/usr/bin/umount
--- فایل‌های متعلق به کاربر ali در پوشه‌ی lab:
lab/docs/Notes.TXT
lab/docs/medium.bin
lab/docs/README.md

-perm -4000 فایل‌هایی را می‌یابد که بیت setuid دارند (اینکه چرا مهم‌اند را در درس دسترسی‌های ویژه می‌بینی)؛ این یک کار امنیتی رایج است. -user، -group مالک را و -perm دسترسی را فیلتر می‌کنند.

مثال ۱۰: locate، جستجوی سریع در پایگاه داده

Section titled “مثال ۱۰: locate، جستجوی سریع در پایگاه داده”

locate از یک پایگاه داده‌ی از پیش ساخته‌شده (توسط updatedb) می‌خواند و بسیار سریع است، ولی فقط اسم/مسیر را جستجو می‌کند:

Terminal window
echo "تعداد os-release: $(locate -c -r '/os-release$')"
locate -r '/os-release$'
خروجی
تعداد os-release: 2
/etc/os-release
/usr/lib/os-release

-r یعنی الگو یک regex است ($ پایان مسیر)، و -c فقط می‌شمارد. نکته‌ی مهم: پایگاه داده کهنه می‌شود:

Terminal window
touch ~/fresh-file-xyz.txt
echo "قبل از updatedb: $(locate fresh-file-xyz.txt | wc -l) نتیجه"
sudo updatedb
echo "بعد از updatedb: $(locate fresh-file-xyz.txt | wc -l) نتیجه"
locate fresh-file-xyz.txt
rm ~/fresh-file-xyz.txt
خروجی
قبل از updatedb: 0 نتیجه
بعد از updatedb: 1 نتیجه
/home/ali/fresh-file-xyz.txt

فایل تازه تا updatedb بعدی دیده نمی‌شود. (در سیستم‌های واقعی یک کار زمان‌بندی‌شده روزانه updatedb را می‌زند.) برای استفاده: locate -i نام (بی‌حساس به حروف)، locate -l 5 الگو (حداکثر ۵ نتیجه). locate روی Ubuntu معمولاً با بسته‌ی plocate (یا mlocate) نصب می‌شود.

پشت پرده: چرا quote؟ و find چطور می‌گردد؟

Section titled “پشت پرده: چرا quote؟ و find چطور می‌گردد؟”

چرا -name "*.log" در quote؟ shell قبل از اجرای find هر الگوی بدون quote را با اسم فایل‌های پوشه‌ی فعلی جایگزین می‌کند. اگر در پوشه‌ی فعلی دو فایل a.log و b.log باشد، find . -name *.log به find . -name a.log b.log تبدیل می‌شود و find خطا می‌دهد:

Terminal window
mkdir -p glob && cd glob
touch a.log b.log
find . -name *.log 2>&1 | head -2
echo "--- با quote:"
find . -name "*.log"
خروجی
find: paths must precede expression: `b.log'
find: possible unquoted pattern after predicate `-name'?
--- با quote:
./a.log
./b.log

find: paths must precede expression: اولین b.log را مسیر گرفته. با quote، الگو دست‌نخورده به find می‌رسد و خودش با اسم هر فایل در همه‌ی زیرپوشه‌ها مقایسه می‌کند.

روش کار find: از مسیر شروع، پوشه را باز می‌کند (فهرست اسم‌ها)، برای هر آیتم اطلاعات inode را می‌خواند (stat: نوع، حجم، زمان‌ها، مالک، دسترسی) و شرط‌ها را به ترتیب از چپ به راست بررسی می‌کند (با کوتاه‌شدن: اگر شرطی نادرست شود، بعدی‌ها بررسی نمی‌شوند). برای همین ترتیب شرط‌ها اهمیت دارد: شرط ارزان (-name) را قبل از گران (-exec) بگذار؛ و -delete یا -exec را آخر. locate این‌ها را انجام نمی‌دهد: یک فهرست فشرده از مسیرها دارد که updatedb هر چند وقت بازسازی می‌کند.

شرط معنی مثال
-name الگو اسم (حساس به حروف) -name "*.log"
-iname الگو اسم بی‌حساس به حروف -iname "*.txt"
-path الگو مسیر کامل -path "*/src/*"
-type f/d/l نوع: فایل، پوشه، لینک -type f
-size +N حجم (c k M G) -size +100M
-mtime ±N تغییر بر حسب روز -mtime +7
-mmin ±N تغییر بر حسب دقیقه -mmin -30
-newer f جدیدتر از فایل -newer ref.txt
-user / -group مالک / گروه -user ali
-perm دسترسی -perm -4000
-empty خالی -empty
-maxdepth N حداکثر عمق -maxdepth 2
عمل معنی
-print چاپ مسیر (پیش‌فرض)
-ls نمایش مثل ls -l
-exec cmd {} \; اجرای دستور برای هر فایل
-exec cmd {} + اجرای دستور یک بار روی دسته‌ی فایل‌ها
-delete حذف (آخرین شرط بگذار!)
ترکیب نماد
و پشت سر هم (یا -a)
یا -o (با \( \))
نه ! یا -not

مثال بالا: find: paths must precede expression. راه‌حل: -name "*.log".

Terminal window
mkdir -p del && cd del && touch keep.txt drop.tmp
echo "قبل: $(ls | tr '\n' ' ')"
find . -delete -name "*.tmp" 2>&1 | head -1
echo "بعد: $(ls | wc -l) فایل باقی ماند"
خروجی
قبل: drop.tmp keep.txt
بعد: 0 فایل باقی ماند

-delete اول آمد و find همه‌چیز (حتی keep.txt) را برداشت (فقط چون این پوشه‌ی تمرینی است نگران نیستیم). راه‌حل: -delete را همیشه آخر بگذار و اول با -print امتحان کن.

۳) اشتباه در علامت + و - برای حجم و زمان

Section titled “۳) اشتباه در علامت + و - برای حجم و زمان”
Terminal window
find lab -type f -size -1M | wc -l
find lab -type f -size +1M | wc -l
خروجی
0
1

-1M یعنی «کمتر از ۱ مگابایت» (همه‌ی فایل‌های کوچک) و +1M یعنی «بیشتر» (فقط big.img). اگر برعکس بنویسی نتیجه‌ی عکس می‌گیری. راه‌حل: با ls -lh یکی را چک کن.

۴) جستجو از / بدون 2>/dev/null و ترسیدن از خطاها

Section titled “۴) جستجو از / بدون 2>/dev/null و ترسیدن از خطاها”

پیام‌های Permission denied هزاران خط می‌شوند و نتیجه‌ی اصلی گم می‌شود. راه‌حل: 2>/dev/null (یا پوشه‌ی شروع را دقیق‌تر کن).

۵) اعتماد به locate برای فایلی که همین الآن ساختی

Section titled “۵) اعتماد به locate برای فایلی که همین الآن ساختی”

مثال ۱۰: تا updatedb نزنی پیدا نمی‌شود. راه‌حل: برای فایل تازه find.

✎ تمرینآسان

در پوشه‌ی lab همه‌ی فایل‌های .py را پیدا کن و بگو چند تا است.

دیدن جواب
Terminal window
mkdir -p lab/src/utils
echo "print(1)" > lab/src/main.py; echo "x=2" > lab/src/utils/helper.py
find lab -name "*.py" -type f | sort
echo "تعداد: $(find lab -name '*.py' -type f | wc -l)"
خروجی
lab/src/main.py
lab/src/utils/helper.py
تعداد: 2
✎ تمرینمتوسط

تمرین اصلی: همه‌ی فایل‌های بزرگ‌تر از ۵۰ مگابایت را در پوشه‌ی خانه پیدا کن. یک فایل ۶۰ مگابایتی بساز (با truncate)، با find ~ -type f -size +50M پیدایش کن، حجمش را با ls -lh ببین و در پایان پاکش کن.

دیدن جواب
Terminal window
mkdir -p ~/downloads && truncate -s 60M ~/downloads/movie.mp4
truncate -s 1M ~/downloads/small.dat
find ~ -type f -size +50M
ls -lh ~/downloads/movie.mp4 | awk '{print $5, $9}'
find ~ -type f -size +50M -delete && echo "پاک شد"
خروجی
/home/ali/lab/tmp/big.img
/home/ali/downloads/movie.mp4
60M /home/ali/downloads/movie.mp4
پاک شد
✎ تمرینسخت

یک گزارش پاکسازی بساز: در پوشه‌ی lab فایل‌های .tmp و .log.1 را که قدیمی‌تر از ۷ روزند فهرست کن (با -exec ls -l)، حجم کل‌شان را با du -ch (یا شمارش بایت) نشان بده، و بعد با -delete فقط همان‌ها را پاک کن؛ در پایان نشان بده چه چیزی ماند.

دیدن جواب
Terminal window
mkdir -p lab2/logs lab2/tmp
echo old > lab2/logs/old.log.1; echo older > lab2/tmp/a.tmp; echo new > lab2/tmp/b.tmp
touch -d "10 days ago" lab2/logs/old.log.1 lab2/tmp/a.tmp
echo "--- نامزدهای پاکسازی:"
find lab2 -type f \( -name "*.tmp" -o -name "*.log.1" \) -mtime +7 -exec ls -l {} + | awk '{print $5, $9}'
echo "حجم کل (بایت): $(find lab2 -type f \( -name '*.tmp' -o -name '*.log.1' \) -mtime +7 -printf '%s\n' | awk '{s+=$1} END{print s+0}')"
find lab2 -type f \( -name "*.tmp" -o -name "*.log.1" \) -mtime +7 -delete
echo "--- باقی‌مانده:"; find lab2 -type f | sort
خروجی
--- نامزدهای پاکسازی:
4 lab2/logs/old.log.1
6 lab2/tmp/a.tmp
حجم کل (بایت): 10
--- باقی‌مانده:
lab2/tmp/b.tmp

-printf '%s\n' اندازه‌ی هر فایل را چاپ می‌کند و awk جمع می‌زند.

؟ آزمونک
  1. کدام دستور فایل‌های .log را در پوشه‌ی فعلی و زیرپوشه‌ها پیدا می‌کند؟

  2. find / -size +100M چه می‌یابد؟

  3. قبل از استفاده از -delete چه کار می‌کنی؟

  4. -exec cmd {} + با -exec cmd {} \; چه فرقی دارد؟

  5. مشکل locate چیست؟

  6. چرا 2>/dev/null در find از / مفید است؟

  • find مسیر شرط‌ها...: -name/-iname (الگو را در quote بنویس)، -type f|d|l، -size +100M، -mtime +7، -mmin، -newer، -user، -perm، -maxdepth.
  • ترکیب: پشت‌سرهم = «و»، -o = «یا» (با \( \))، ! = «نه».
  • عمل: -print (پیش‌فرض)، -ls، -exec cmd {} \; (برای هر فایل) یا {} + (دسته‌ای)، -delete (آخر؛ اول بدون آن امتحان کن).
  • از / که شروع کنی 2>/dev/null خطاهای دسترسی را دور می‌ریزد.
  • locate (با updatedb) سریع ولی ممکن است کهنه باشد؛ برای فایل تازه از find.
  • ترتیب شرط‌ها مهم است؛ شرط ارزان‌تر اول.
برگه‌ی تقلب این درس
دستورکاری که می‌کند
find . -name "*.log"اسم با الگو (حساس به حروف)
find . -iname "*.txt"بی‌حساس به حروف
find / -size +100M 2>/dev/nullفایل‌های بزرگ‌تر از ۱۰۰ مگابایت
find . -mtime -1تغییرکرده در ۲۴ ساعت اخیر
find . -type dفقط پوشه‌ها
find . -name "*.tmp" -deleteحذف نتایج (اول بدون -delete امتحان کن)
find . -name "*.py" -exec wc -l {} +اجرای دستور روی نتایج (دسته‌ای)
find . -maxdepth 1فقط یک سطح
find . \( -name "*.a" -o -name "*.b" \)یا
locate -i nameجستجوی سریع در پایگاه داده
sudo updatedbبه‌روز کردن پایگاه locate