انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید

نویسنده موضوع: راهنمای دستور find  (دفعات بازدید: 3255 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین محسن صفری

  • Jr. Member
  • *
  • ارسال: 47
  • جنسیت : پسر
    • صفری آنلاین
راهنمای دستور find
« : 14 شهریور 1393، 12:08 ب‌ظ »
نقل‌قول
قبل از مطالعه :

این راهنما را چند وقت پیش نوشته و در آدرس  http://safarionline.ir/site/index.php?title=%D8%AF%D8%B3%D8%AA%D9%88%D8%B1_find منتشر کرده ام .  فکر می کنم مخاطبان این نوشتار در این مکان بیشتر خواهد بود ولی به هر حال اگر مایل به مشاهده این متن در حالت نمایشی بهتر هستید می توانید به آدرس فوق هم مراجعه کنید.

مقدمه

find یکی از مهمترین دستورات یونیکس است که دیر یا زود به آن نیاز مبرمی پیدا می کنید . با یادگیری دستور find و به کار بردن عملی آن در کارهای روزانه ، هر روز می توانید کاربرد جدیدی برای آن پیدا کنید ، مثلا با اتصال خروجی این دستور به ورودی دستور دیگر از طریق pipe می توانید عملیات گوناگونی را روی فایل هایی که پیدا کرده اید انجام دهید و یا اینکه مستقیما از سوییچ exec- دستور find استفاده کنید . exec- برای تمامی فایل های یافته شده اجرا خواهد شد و می تواند شامل هر دستوری باشد . وقتی که در find خبره شدید احتمالا به خود خواهید گفت بدون find چطور زندگی می کردم ؟!


طرح چند پرسش
  • دنبال ویدیویی به نام moammaye_hasti.mp4 از شجریان می گردم ولی پیداش نمی کنم.
  • فیلم های سینمایی من همه بالای ۶۰۰-۷۰۰ مگابایت هستن ولی متاسفانه توی فولدرهای مختلف گم شدن . از همه بدتر اینکه اسمشون رو هم چیزهای الکی گذاشتم مثلا ddd.mp4 یا london.mp4
  • ماه گذشته دو تا سی دی کامل mp3 کپی کردم توی کامپیوتر ولی همه شون رو گم کردم !
  • می خوام عکس های موجود در این دایرکتوری و زیر دایرکتورهاش رو پاک کنم ولی دایرکتوری خیلی بزرگه و پر از اطلاعات . حتی اگه وقتش رو داشته باشم و به صورت دستی این کار رو انجام بدم ، اون موقع همش ناراحت اینم که آیا همه عکس ها رو پاک کردم یا خدایی ناکرده چند تایی شون از دستم در رفته !
  • می خوام لیست کل فایل های این دایرکتوری و کلیه زیر دایرکتوری های زیرش رو به دست بیارم . ls کمکی بهم نکرد.
  • می خوام کلیه فایل هایی که owner شون reza هست رو به نام mohsen در بیارم . می دونم که باید از chown استفاده کنم ولی از کجا کلیه فایل های رضا رو شناسایی کنم و چه طوری اون همه chown بنویسم ؟

جواب این چند پرسش و بسیاری پرسش های دیگر دستور find هست .


جستجوی کلیه فایل ها

شکل کلی و ساده دستور find به صورت زیر است :


$ find path experssion

path مسیر مورد جستجو است . جستجو در کلیه دایرکتوری های زیر مجموعه path به صورت تو در تو (recursive) و تا آخرین دایرکتوری انجام می شود مگر اینکه عمق جستجو را معلوم کرده باشیم که در این صورت ، جستجو تا عمق انتخاب شده انجام خواهد شد . عمق جستجو با استفاده از سوییچ d- ( ابتدای کلمه depth ) مشخص می شود .


$ find path -d 3 other-experssions

در دستور بالا find تا سه زیر دایرکتوری را جستجو می کند .


  • لیست کلیه فایل ها و دایرکتوری های خانه ( و زیر دایرکتوری های آن )
$ find ~

این دستور فاقد experssion است و به صورت اتوماتیک لیست فایل های یافت شده را در خروجی استاندارد چاپ می کند . ~ ( تیلدا ) نشان دهنده دایرکتوری خانه کاربر جاری می باشد .


جستجو بر مبنای نام فایل

برای جستجو بر مبنای نام از دو سوییچ name- و iname- استفاده می کنیم . حرف i در ابتدای سوییچ iname- ابتدای کلمه case-insensitive است به این معنا که کوچکی و بزرگی حروف اهمیتی ندارد . چنانچه در عبارتی که جلوی سوییچ ها نوشته می شود از wildcard استفاده نکرده باشیم ، find دقیقا عبارت مورد نظر را جستجو می کند . در صورت استفاده از wildcard دستور find بر مبنای wildcard تصمیم گیری می کند . * به معنای هر تعداد کاراکتر و ? به معنای دقیقا یک کاراکتر می باشد .


  • جستجو کردن فایل moammaye_hasti.mp3 در دایرکتوری خانگی ( و زیر دایرکتوری های آن )
$ find ~ -iname "moammaye_hasti.mp3"

برای اینکه جستجو ، هم فایلهای با حروف کوچک و هم فایل های با حروف بزرگ را شامل شود از سوییچ iname- استفاده می کنیم . اگر از اسم فایل اطمینان دارید می توانید نام را دقیقا مانند نام فایل بنویسید و از سوییچ name- استفاده کنید.


  • جستجو کردن کلیه فایل های mp3 علی
$ find ~ali -iname "*.mp3"

  • جستجو کردن کلیه فایل های پنهان موجود در دایرکتوری جاری و زیر دایرکتوریهای آن
$ find . -name ".*"

می دانید که فایل پنهان فایلی است که با دات (.) شروع شود .


  • کلیه فایل ها و دایرکتوری های سه حرفی را نمایش بده . زیر دایرکتوری ها را جستجو نکن .
$ find ~ -name "???" -d 1

فراموش نکنید چنانچه از * و یا ? استفاده می کنید حتما متن را با استفاده از "" و یا ′′ quote کنید و یا اینکه قبل از کاراکتر ویژه * و یا ? علامت \ قرار دهید و یا به عبارت دیگر آن را escape کنید .


ارسال خروجی find به xargs

تا به حال با پیغام arguments too long مواجه شده اید ؟ علت این پیغام چیست ؟ در واقع پوسته یا shell تا حد معینی می تواند آرگومانهای خط فرمان را به برنامه فراخوانده شده ارسال کند . وقتی این تعداد از حد معین شده توسط پوسته بیشتر می شود ، پوسته پیغام arguments too long می دهد . برای حل این مشکل و البته برای کاربرد در وضعیتهای دیگر دستور xargs به کمک می آید .


$ ls | xargs echo

xargs محتوای خوانده شده از ورودی استاندارد را به عنوان آرگومان به دستور خواسته شده می فرستند . در دستور فوق ورودی استاندارد به سمت pipe تغییر جهت یافته است و لذا xargs محتوای ارسالی در pipe ، که همان خروجی دستور ls است را می خواند و آن را به عنوان آرگومانهای ورودی به دستور echo ارسال می کند . xargs محدودیت تعداد آرگومان پوسته را می داند و لذا دیگر شاهد پیغام arguments too long نخواهید بود .


  • برای حذف کلیه فایل های mp3 از دایرکتوری جاری به شیوه زیر نیز می توان عمل کرد :
$ ls *.mp3 | xargs rm

دستور ls کلیه فایلهای خاتمه یافته به پسوند mp3 را لیست می کند و آن را به pipe می فرستد . xargs از pipe می خواند و محتوای خوانده شده را به عنوان آرگومانهای دستور rm منظور می کند و سپس rm را اجرا می کند . اگر لیست فایل های mp3 بسیار زیاد باشد در این صورت xargs یکبار دستور rm را با تعداد کافی آرگومان خوانده شده از پایپ اجرا می کند و سپس دوباره اقدام به اجرای دستور rm با آرگومانهای جدید می نماید . این عمل تا زمانی که pipe خالی شود ادامه می یابد .


  • دستور بالا را می توان با استفاده از find نوشت . توجه کنید چون find جستجو را به صورت تو در تو انجام می دهد برای پیاده سازی دقیق دستور بالا باید عمق جستجو را ۱ بگذاریم .
$ find . -d 1 -iname "*.mp3" | xargs rm

عمق جستو با سوییچ d- مشخص می شود .


متاسفانه دستور xargs در مورد فایل هایی که در نامشان space دارند درست عمل نمی کند .


حل مشکل space در xargs و find

دستور xargs بر مبنای کاراکترهای space و new line کار می کند ، یعنی اگر میان نام یک فایل space باشد xargs آن را به چند نام تقسیم می کند ، چون کارکتر جداکننده آن space است .


خوشبختانه دستور find دارای سوییچی به نام print0- می باشد که در آخر تمام موارد یافته شده کاراکتر NULL را قرار می دهد و همچنین دستور xargs نیز دارای سوییچی به نام 0- می باشد که کاراکتر جدا کننده را به NULL تغییر می دهد .


  • دو دستور زیر و خروجی های آن ها را ملاحظه بفرمایید .
$  find . -name "Untitled 1.odt" | xargs ls -l
ls: ./Untitled: No such file or directory
ls: 1.odt: No such file or directory
 
$ find . -name "Untitled 1.odt" -print0 | xargs -0 ls -l
-rw-r--r--  1 mohsen  wheel  31308 Apr  1 17:33 ./Untitled 1.odt


جستجو بر مبنای نوع (type) فایل

گاهی اوقات نیاز به جستجو در میان نوع خاصی از فایل ها داریم . برای این منظور از سوییچ type- به همراه کاراکترهای تعریف شده زیر استفاده می کنیم .

    b : فایل ویژه از نوع block یا block special file
    c : فایل ویژه از نوع character یا character special file
    d : دایرکتوری
    f : فایل معمولی
    l : لینک
    s : سوکت socket


  • لیست کلیه فایل های معمولی در دایرکتوری جاری و لیست کامل اطلاعات آن
$ find . -type f -d 1 | xargs ls -l

  • لیست کلیه لینک ها در دایرکتوری خانگی ( و زیر دایرکتوری های آن )
$ find ~ -type l

  • لینک های موجود در دایرکتوری خانگی به کجا اشاره می کنند ؟
$ find ~ -d 1 -type l | xargs ls -l | awk '{print $9 " " $10 " " $11}'

علامت + و -

علامت + به کار رفته قبل از عدد به معنای بزرگتر از یا بیشتر از می باشد . علامت - به کار رفته قبل از عدد به معنای کوچکتر از یا کمتر از می باشد .

     عبارت size -20M- یعنی سایز فایل کمتر از ۲۰ مگابایت باشد و عبارت mtime -2- یعنی تاریخ ویرایش فایل کمتر از ۲ روز گذشته باشد .

    عبارت size +100K- یعنی فایلهایی که سایزشان بیشتر از ۱۰۰ کیلو بایت باشد و عبارت atime +2- یعنی فایلهایی که تاریخ آخرین دسترسی به آنها بیشتر از ۲ روز گذشته باشد .


جستجو بر مبنای بزرگی (size) فایل

برای جستجو بر مبنای سایز از سوییچ size- استفاده می کنیم . به دنبال size- عدد صحیحی می آید . چنانچه این عدد بدون هیچ گونه کاراکتر بعدی باشد به معنای تعداد دقیق بلاک اشغال شده توسط برنامه می باشد . متاسفانه فضای هر بلاک برای برنامه های مختلف متفاوت است . مثلا در سیستم FreeBSD که من استفاده می کنم دستور ls -s که تعداد بلاک هر فایل را بر می گرداند هر بلاک را ۱۰۲۴ بایت حساب می کند در صورتیکه هر بلاک دستور find تعداد ۵۱۲ بایت می باشد .

$ ls -ls 5.txt
4 -rw-r--r--  1 mohsen  wheel  1058 Apr  6 21:25 5.txt


دستور فوق نشان می دهد که فایل 5 دارای 1058 بایت است و 4 بلاک اشغال کرده است . دستور ls بلاک ها را در واحدهای چهار تایی اختصاص داده است در حالیکه تعداد بلاک مصرف شده واقعی با حجم هر بلاک 1024 بایت دو بلاک است . ولی دستور find بلاکها را ۵۱۲ بایت حساب می کند لذا عدد بلاک مصرف شده برای این فایل از نظر دستور find تعداد ۳ بلاک است . این موضوع را با دستور زیر تست می کنیم .

$ find -size 3 | xargs ls -ls
4 -rw-r--r--  1 mohsen  wheel  1058 Apr  6 21:25 ./5.txt


موضوع پیجیده شد ؟ خوشبختانه راههای فرار خوبی وجود دارد ! می توان بعد از عدد صحیح از کاراکترهای زیر استفاده کرد.

    c : کاراکتر . مثلا 27c یعنی ۲۷ کاراکتر یا ۲۷ بایت
    k : کیلو بایت . مثلا 27k یعنی ۲۷ کیلو بایت . ( توجه کنید k با حرف کوچک نوشته شده است )
    M : مگا بایت . مثلا 27M یعنی ۲۷ مگا بایت
    G : گیگا بایت . مثلا 27G یعنی ۲۷ گیگا بایت
    T : ترا بایت . مثلا 27T یعنی ۲۷ ترا بایت
    P : پتا بایت . مثلا 27P یعنی ۲۷ پتا بایت


  •     لیست فایلهای MP4 که سایز آنها بیشتر از ۶۰۰ مگا بایت است :
$ find ~ -type f -iname "*.mp4" -size +600M

   
  • لیست فایلهای jpg که بین ۴۰۰ کیلو بایت تا ۵ مگابایت هستند :
$ find ~ -type f -iname "*.jpg" -size +400k -size -5M

دستور بالا نشان می دهد که زمانی که دو یا چند شرط وجود داشته باشند تمامی شرط ها می بایست true باشند یا به عبارت دیگر شرط ها با هم AND می شوند .


جستجو بر مبنای سطح دسترسی (permission) فایل

سوییچ perm- برای یافتن فایل با سطوح دسترسی مشخص استفاده می شود . عدد قرار گرفته در جلو سوییچ می بایست عددی در مبنای ۸ باشد .


  •     فایل های دارای اجازه دسترسی ۷۷۷ را نمایش بده
$ find ~ -perm 777

  • فایل های دارای اجازه دسترسی ۷۵۵ را نمایش بده
$ find ~ -perm 755

بعضی اوقات نیازی به دانستن اجازه دسترسی کامل فایل ندارید و فقط یک مجوز برای شما مهم است . مثلا می خواهید بدانید گروه در کدام فایل ها اجازه نوشتن دارد . برای این موارد سریعا ترکیب rwx rwx rwx را برای فایل مورد نظر تشکیل دهید . بدیهی است که rwx ها به ترتیب از چپ به راست مجوزهای صاحب فایل ، گروه و دیگران هستند . زیر مجوز هایی که برای شما اهمیتی ندارند صفر بگذارید و مجوز های که لازم است داشته باشند را یک قرار دهید . عدد حاصله را در مبنای هشت بنویسید و با یک علامت - پیش از آن ، جلوی سوییچ perm- قرار دهید .


علامت - پیش از عدد permission می گوید که اجازه دسترسی واقعی فایل را با عدد جلوی permission به صورت بیتی AND کن و اگر حاصل درست بود فایل را نمایش بده ( یعنی آن فایل مجوزی که برای شما مهم بوده است را دارد. )


  •     کدام فایل ها مجوز نوشتن توسط گروه را دارند ؟

rwx rwx rwx

000 010 000

عدد هشت بیتی حاصل 020 می باشد . از این عدد به صورت زیر استفاده می کنیم .


$ find ~ -perm -020

  • لیست کامل فایل های اجرایی را نمایش بده .

rwx rwx rwx

001 000 000

عدد هشت بیتی حاصل 001 می باشد .


$ find ~ -type f -perm -001

سوییچ perm- همچنین قابلیت شناسایی بیت های SUID و SGID و sticky bit را نیز دارد . برای این منظور فقط کافیست ترکیب SUID SGID sticky را در سمت چپ rwx صاحب فایل تشکیل دهید و مانند سابق عدد هشت بیتی حاصل را با علامت - بعد از سوییچ perm- قرار دهید .


  •     تمام فایل هایی که بیت SUID آن فعال است را پیدا کن .

SUID/SGID/sticky rwx rwx rwx

000 000 000 0 0 1

عدد هشت بیتی حاصل 4000 می باشد .

$ find /usr/bin -type f -perm -4000 -print0 | xargs -0 ls -lh | head -n 5
 
-r-sr-xr-x  4 root  wheel     22k Dec  4  2012 /usr/bin/at
-r-sr-xr-x  4 root  wheel     22k Dec  4  2012 /usr/bin/atq
-r-sr-xr-x  4 root  wheel     22k Dec  4  2012 /usr/bin/atrm
-r-sr-xr-x  4 root  wheel     22k Dec  4  2012 /usr/bin/batch
-r-sr-xr-x  6 root  wheel     18k Dec  4  2012 /usr/bin/chfn

گاهی اوقات می خواهید فایل هایی را پیدا کنید که مجوز خاصی را نداشته باشند . برای اینگونه موقعیت ها باید ابتدا شرط داشتن مجوز را بنویسید و سپس آن شرط را نقیض کنید . برای این منظور در بخش های بعد عملگرهای منطقی را بررسی خواهیم کرد .


جستجو بر مبنای زمان ویرایش ، زمان دسترسی و زمان تغییر i-node

به طور کلی جستجوی زمانی را بر مبنای دو پارامتر روز و دقیقه انجام می دهیم .


جستجو بر مبنای روز

سوییج های جستجو بر مبنای روز به صورت زیر تعریف می شوند :

    mtime- : برگرفته از عبارت modified time یا زمان آخرین ویرایش فایل . از آنجایی که یونیکس زمان ایجاد فایل را ذخیره نمی کند به عنوان زمان ایجاد فایل هم می تواند استفاده شود .
    atime- : برگرفته از عبارت accessed time یا زمان آخرین دسترسی به فایل .
    ctime- : بر گرفته از عبارت i-node change time یا زمان آخرین تغییر اطلاعات i-node . چنانچه نام فایل ، صاحب فایل ، گروه و یا تعداد لینک های داده شده به فایل و ... تغییر کند بدون اینکه محتوای فایل مورد ویرایش قرار گیرد این تاریخ زمانی جلوتر از زمان آخرین ویرایش فایل خواهد داشت .


  •     فایل هایی که ۷ روز پیش ویرایش شده را نمایش بده .
$ find ~ -mtime 7

همین مثال می تواند به صورت زیر با استفاده از علامت های + و - نیز نوشته شود.


$ find ~ -mtime +6 -mtime -7

یعنی زمان ویرایش فایل بیشتر از ۶ روز و کمتر از 7 روز پیش باشد. علامت + شامل همان عدد نمی شود ولی علامت - خود عدد را نیز شامل می شود.


  •     فایل هایی که بیشتر از ۳۰ روز است که از آنها استفاده نکرده ام .
$ find ~ -atime +30 -type f

  •     نمایش فایل هایی که بیشتر از یک روز پیش و کمتر از دو روز پیش به آن ها دسترسی داشته ام .
$ (echo -e current date :  `date` "\n";find . -type f -d 1 -atime -2 -atime +1 -print0 | xargs -0 ls -lut)
 
current date :  Fri Apr 11 16:15:37 IRDT 2014
 
-rw-r--r--  1 mohsen  wheel      11710 Apr  9 23:20 ./b.result
-rw-r--r--  1 mohsen  wheel  155845071 Apr  9 23:13 ./download36.mp4
-rw-r--r--  1 mohsen  wheel    1292918 Apr  9 18:01 ./b.flv
-rw-r--r--  1 mohsen  wheel    2168490 Apr  9 18:01 ./recovered2.flv
-rw-r--r--  1 mohsen  wheel    3022870 Apr  9 18:00 ./recovered1.flv

همانطوری که مشاهده می کنید علامت + شامل خود عدد ( در اینجا ۱ روز ) نمی شود ولی علامت منفی شامل عدد ( در اینجا ۲ روز ) می شود .


جستجو بر مبنای دقیقه

سه سوییچ زیر برای جستجو بر مبنای دقیقه مورد استفاده قرار می گیرند :

    mmin- : بر گرفته از عبارت modified minute
    amin- : بر گرفته از عبارت accessed minute
    cmin- : برگرفته از عبارت i-node change minute


کاربرد این سوییچ ها دقیقا مانند سوییچ های بخش قبل هستند با این تفاوت که همه چیز در اینجا معنای دقیقه می دهد .


  •     فایلهایی که کمتر از ۶۰ دقیقه قبل ویرایش شده اند را نمایش دهید .
$ find . -type f -mmin -60

  •     فایل هایی که کمتر از ۴۰ دقیقه پیش آن ها را مشاهده کرده ام را نمایش دهید .
$ find . -type f -amin -40

جستجوی زمانی بر مبنای زمان ویرایش یک فایل

اگر می خواهید متوجه شوید زمان آخرین ویرایش چه فایل هایی از فایل داده شده کمتر است از سوییچ newer- استفاده کنید.


  •     چه فایل هایی از فایل tmp.sh جدیدتر می باشند ؟
$ ls -l tmp.sh
-rwxr-xr-x  1 mohsen  wheel  34 Mar 24 21:56 tmp.sh*
 
$ find . -d 1 -newer tmp.sh | xargs ls -lt | head -n 5
-rw-r--r--  1 mohsen  wheel   0 Apr 11 19:05 ./4
-rw-r--r--  1 mohsen  wheel   0 Apr 11 19:05 ./3
-rwxr-xr-x  2 mohsen  wheel   2 Mar 30 22:40 ./1
-rwxr-xr-x  2 mohsen  wheel   2 Mar 30 22:40 ./2
lrwxr-xr-x  1 mohsen  wheel  21 Mar 30 17:08 ./.profile -> /home/mohsen/.profile

جستجو بر مبنای صاحب (owner) و گروه (group) فایل

از سوییچ user- برای جستجوی فایلها بر مبنای نام کاربری یا شماره یکتای صاحب فایل استفاده می شود . شماره یکتای هر کاربر را می توانید در فایل etc/passwd/ مشاهده کنید .

$ cat /etc/passwd | grep ^mohsen
 
mohsen:*:1001:1001:Mohsen Safari:/home/mohsen:/usr/local/bin/bash

مثال بالا خط مربوط به کاربر mohsen در فایل etc/passwd/ را نشان می دهد که دارای شماره کاربری ۱۰۰۱ می باشد .


از سوییچ group- برای جستجوی فایلها بر مبنای نام گروه و یا شماره ی یکتای گروه استفاده می شود . شماره یکتای هر گروه را می توانید در فایل etc/group/ مشاهده کنید .

$ cat /etc/group | grep ^mohsen
 
mohsen:*:1001:

در مثال بالا مشاهده می کنید که گروه mohsen دارای شماره یکتای ۱۰۰۱ می باشد .


  •     کلیه فایل هایی که SGID آن ها به wheel ست شده است را پیدا کنید .

$ find ~ -group wheel -perm -2000

جستجو بر مبنای i-number

تا به حال دستور ls -li را اجرا کرده اید ؟ نمونه خروجی این دستور را ببینید :


$ ls -li
total 64
11397272 drwxr-xr-x  6 mohsen  wheel   512 Apr  5 20:23 ./
11318506 drwxr-xr-x  3 mohsen  wheel   512 Mar 21 21:34 ../
11396871 lrwxr-xr-x  1 mohsen  wheel    21 Mar 30 17:08 .profile@ -> /home/mohsen/.profile
11396876 -rw-r--r--  2 mohsen  wheel     2 Mar 30 22:40 1
11396876 -rw-r--r--  2 mohsen  wheel     2 Mar 30 22:40 2
11396865 -rwxr-xr-x  1 mohsen  wheel    34 Mar 24 21:56 2.2.sh*
11879926 drwxr-xr-x  3 mohsen  wheel   512 Mar 30 18:12 DIR/
11396862 -rw-r--r--  1 mohsen  wheel   252 Mar 24 20:51 args-no.sh
11396866 -rwxr-xr-x  1 mohsen  wheel  2054 Mar 23 16:02 cleanup*
12039467 drwxrwxr-x  2 mohsen  wheel   512 Apr  5 20:23 d1/
12039468 dr-xr-xr-x  2 mohsen  wheel   512 Apr  5 20:23 d2/
12039469 drwxr-xr-x  2 mohsen  wheel   512 Apr  5 20:23 d3/
11396867 -rw-r--r--  1 mohsen  wheel   352 Mar 24 21:49 log
11396875 -rwxr-xr-x  1 mohsen  wheel  8780 Mar 24 20:59 readme*
11396878 -rwxr-xr-x  1 mohsen  wheel   403 Mar 21 22:11 swap.sh*

عدد های قرار گرفته در سمت چپ هر سطر i-number نامیده می شود و شماره درایه مربوط به آن فایل در داخل جدول i-table یا inode-table می باشند .

دستور find قابلیت جستجو بر مبنای i-number را دارد . برای این منظور می توانید از سوییچ inum- استفاده کنید . می بایست بعد از inum- شماره i-number فایل مورد را قرار دهید .


  •     فایل دارای i-number به شماره ۱۱۳۹۶۸۶۶ را از طریق دستور find بیابید .
$ find . -inum 11396866 | xargs ls -li
11396866 -rwxr-xr-x  1 mohsen  wheel  2054 Mar 23 16:02 ./cleanup

برای مشاهده صحت عملکرد find خروجی آن را از طریق pipe به دستور xargs ls -li ارسال می کنیم . سوییچ i در دستور ls همانگونه که می دانید شماره i-number هر فایل را بر می گرداند .


جستجوی فایل های خالی (empty)

از سوییچ empty- برای یافتن فایل های خالی استفاده می شود .

$ >1 ; >2 ; >3
$ echo "salam" >4
$ find . -empty | xargs ls -l
-rw-r--r--  1 mohsen  wheel  0 Apr  7 15:32 ./1
-rw-r--r--  1 mohsen  wheel  0 Apr  7 15:32 ./2
-rw-r--r--  1 mohsen  wheel  0 Apr  7 15:32 ./3

همانطور که در ریز لیست فایل ها می بینید حجم تمام این فایل ها صفر بایت است و در واقع خالی هستند .


  •     از سوییچ empty- برای یافتن دایرکتوری های خالی هم می توان استفاده کرد .
$ mkdir newdir
$ echo "salam" >newdir/1.txt
$ mkdir emptydir
$ find . -type d -empty
./emptydir

سوییچ exec- و ok-

تا کنون برای ارسال خروجی دستور find به برنامه های دیگر از pipe و xargs استفاده کرده ایم ولی این شیوه تنها راه حل نیست بلکه می توانیم از سوییچ exec- خود دستور find استفاده کنیم . بعد از exec- می توانیم هر دستوری را استفاده کنیم .

  •     سوییچ ok- دقیقا مانند سوییچ exec- است با این تفاوت که قبل از اجرای دستور از شما می پرسد که آیا دستور را اجرا کند یا خیر.
  •     متغیر {} در سوییچ exec- به معنای نام فایل یافته شده می باشد . با یافتن نتیجه جدید مقدار {} رونویسی می شود .
  •     exec- یکبار به ازای هر فایل یافته شده اجرا می شود به عنوان مثال اگر جستجویی ۴۰ نتیجه داشته باشد و در این جستجو از سوییج exec- استفاده کرده باشیم ، exec- چهل بار اجرا خواهد شد ، در صورتیکه با استفاده از pipe و xargs ، دستور xargs چهل نتیجه یافته شده را به عنوان آرگومان دستور بعدی منظور کرده و به احتمال بسیار زیاد فقط یکبار دستور مورد نظر را اجرا می کند . از طرف دیگر xargs در مورد فایلهایی که در داخل نامشان space دارند به صورت پیش فرض درست عمل نمی کند ( مشاهده راه حل ) و در این مواقع بهتر است از سوییچ exec- استفاده کنید . تصمیم گیری در مورد استفاده از xargs یا سوییچ exec- با توجه به شرایط و تجربه با شما خواهد بود .
  • بعد از سوییج exec- دستوری می آید که در صورت پیدا شدن یک فایل اجرا خواهد شد . از آنجا که این دستور باید مستقیما و به طور کامل به دستور find ارسال شود تا در موقع لزوم اجرا شود ، می بایست کلیه کاراکترهایی که shell آن ها را تفسیر می کند را escape کنیم . از جمله این کاراکترها سمی کالن و * و ( و ) و ? می باشند . برای escape کردن این کاراکترها قبل از آنها یک \ قرار دهید . از طرفی find می بایست نقطه پایان دستور exec- را شناسایی کند . برای نشان دادن نقطه پایان دستور exec- از ; استفاده می کنیم . ; در پوسته به معنای جدا کننده دستورها می باشد لذا ; نیز می بایست escape شود .

  •     فایل های mp3 دایرکتوری جاری و زیر داکتوری های آن را حذف کنید . لطفا قبل از حذف از من سوال کنید.


$ find . -iname "*.mp3" -ok rm {} \;

دستور فوق فایل های mp3 را یافته و بعد از پرسیدن اینکه آیا دستور اجرا شود یا خیر ، در صورت موافقت ، دستور rm را روی فایل مورد نظر ( {} ) اجرا می کند . ok- به ازای هر نتیجه یکبار از شما می پرسد که آیا دستور را اجرا کند یا خیر . بنابر این شما می توانید دستور را روی بعضی از فایل ها اجرا کنید و روی بعضی فایل ها اجرا نکنید .


  •     از کلیه فایل های txt در دایرکتوری فعلی backup بگیرید .


$ find . -d 1 -iname "*.txt" -exec mv {} {}.bak \;

   
  • متاسفانه در اثر بی دقتی فایلی به صورت زیر ایجاد شده است که حاوی تعداد زیادی space می باشد . چه طور می توانم آنرا حذف کنیم .

$ ls -li
12039479 -rw-r--r--  1 mohsen  wheel  0 Apr  7 16:02 o      o

ساده ترین راه استفاده از دستور find به همراه سوییچ های inum- و exec- می باشد .


$ find . -inum 1203979 -exec rm {} \;

شیوه بالا برای انجام هر گونه عملیات روی فایلهایی که دارای کاراکترهای ویژه هستند و یا اینکه نامشان در ترمینال به درستی نمایش داده نمی شود مناسب است .


  • مجوز کلیه فایل های داخل دایرکتوری جاری که با عدد شروع می شوند را به ۷۵۵ تغییر دهید .
$ find . -d 1 -name "[0-9]*" -type f -exec chmod 755 {} \;

استفاده از AND و OR و NOT

به صورت پیش فرض کلیه شرط های موجود در دستور find با هم AND می شوند ولی ما می توانیم با استفاده از چند سوییچ و عملگر ! روند پیش فرض find را تغییر دهیم .

    عملگر ! قبل از شرط به معنای نقیض شرط مشخص شده می باشد .


  •     فایل هایی که بزرگتر از ۳۴ کاراکتر نیستند را نمایش بدهید .

$ find . -d 1 -size -34c
$ find . -d 1 ! -size +34c

دو دستور فوق تاحدودی معادل یکدیگر می باشند . دستور اول می گوید سایز فایل کمتر از ۳۴ کاراکتر و دستور دوم می گوید سایز فایل بیشتر از ۳۴ کاراکتر نباشد ولی دستور اول فایل های ۳۴ کاراکتری را نشان نمی دهد ولی دستور دوم نشان می دهد .


سوییچ a- به معنای AND و سوییچ o- به معنای OR می باشد . شرط ها را می توانیم با پرانتز گروه بندی کنیم . فراموش نکنید به علت اینکه پرانتز برای پوسته معنا دارد آنرا حتما با \ (بک اسلش) escape کنید .


  •     فایل هایی که در اسمشان حسن یا حسین می باشد را نمایش بدهید .
$ find . \( -iname "*hassan*" -o -iname "*hossein*" \)

دستور فوق می تواند به صورت زیر نیز نوشته شود .


$ find . -iname "*hassan*" -print -o -iname "*hossein*" -print

  •     فایل هایی که دیگران اجازه هیچ گونه دسترسی به آن را ندارند نمایش بدهید .

$ find . -d 1 ! \( -perm -001  -o -perm -002  -o -perm -004 \)  -print0 | xargs -0 ls -ld
 
-rwxr-x---  1 mohsen  wheel  0 Apr 12 16:10 ./1
-rwxr-x---  1 mohsen  wheel  0 Apr 12 16:10 ./2
-rwxr-x---  1 mohsen  wheel  0 Apr 12 16:10 ./3
-rwxr-x---  1 mohsen  wheel  0 Apr 12 16:10 ./4

دستور فوق می تواند به صورت زیر نیز نوشته شود :


$ find . -d 1 ! -perm 001 ! -perm 002 ! -perm -004 -print0 | xargs -0 ls -ld
 
-rwxr-x---  1 mohsen  wheel  0 Apr 12 16:10 ./1
-rwxr-x---  1 mohsen  wheel  0 Apr 12 16:10 ./2
-rwxr-x---  1 mohsen  wheel  0 Apr 12 16:10 ./3
-rwxr-x---  1 mohsen  wheel  0 Apr 12 16:10 ./4

پاسخ پرسش های مطرح شده

  •     پیدا کردن ویدیوی moammaye_hasti.mp4
$ find ~ -type f -iname "moammaye_hasti.mp4"

  •     یافتن ویدیوهای حجیم با حجم بالای ۶۰۰ مگا بایت
$ find ~ -type f -size +600M

  •     پیدا کردن mp3 هایی که ماه گذشته ریخته بودم توی کامپیوتر . فکر می کنم بین ۳۰ تا ۳۵ روز گذشته بود؟!
$ find ~ -type f -iname "*.mp3" -ctime +29 -ctime -35

  •     حذف کردن عکسها . عکسهام همه پسوند jpg دارند . اگر هم نداشته باشند راحتترم که چند بار دستور find رو برای حذف پسوندهای مختلف صدا بزنم .
$ find ~/doc/BBAAB‌‌B -type f -iname "*.jpg" -exec rm {} \;

  •     لیست کل فایل های دایرکتوری خانه و زیر دایرکتوری های آن . جایی که ls به راحتی کمک نمی کنه !
$ find ~ -type f

  •     فایل های رضا را به محسن تغییر مالکیت بده
$ find ~ -user reza -ok chown mohsen {} \;

دستور بالا به شرطی اجرا خواهد شد که مجوز های لازم را داشته باشید .

آفلاین doomhammer65ir

  • High Hero Member
  • *
  • ارسال: 1572
  • جنسیت : پسر
    • IRAN Backup
پاسخ : راهنمای دستور find
« پاسخ #1 : 15 شهریور 1393، 12:49 ب‌ظ »
عالی++++

آفلاین abedzadeh

  • High Hero Member
  • *
  • ارسال: 1597
  • جنسیت : پسر
  • aliila
پاسخ : راهنمای دستور find
« پاسخ #2 : 15 شهریور 1393، 12:54 ب‌ظ »
+1
خیلی کامل و عالی بود
ممنون
به گروه کاربران اوبونتوی ایرانی در جامعه ی استیم بپیوندید
http://steamcommunity.com/groups/Ubuntu-Iran
بازی های تحت پوشش : Dota2

آفلاین محسن صفری

  • Jr. Member
  • *
  • ارسال: 47
  • جنسیت : پسر
    • صفری آنلاین
پاسخ : راهنمای دستور find
« پاسخ #3 : 15 شهریور 1393، 06:00 ب‌ظ »
خواهش می کنم . شما لطف دارید.

آفلاین ارباب!

  • Sr. Member
  • *
  • ارسال: 448
  • جنسیت : پسر
پاسخ : راهنمای دستور find
« پاسخ #4 : 15 شهریور 1393، 06:33 ب‌ظ »
+1!
دوست عزیز ممنونم! معلومه که زحمت کشیدید!
Void Linux + XFCE

آفلاین محسن صفری

  • Jr. Member
  • *
  • ارسال: 47
  • جنسیت : پسر
    • صفری آنلاین
پاسخ : راهنمای دستور find
« پاسخ #5 : 15 شهریور 1393، 09:38 ب‌ظ »
+1!
دوست عزیز ممنونم! معلومه که زحمت کشیدید!

خواهش می کنم . امیدوارم برای جامعه کاربران مفید باشه .

آفلاین vesal2012

  • Jr. Member
  • *
  • ارسال: 80
  • جنسیت : پسر
پاسخ : راهنمای دستور find
« پاسخ #6 : 17 مهر 1393، 11:29 ق‌ظ »
خب اگه خواستم فارسی سرچ کنم چهار کنم؟