كيف تستخدِم أمرَي find و locate للبحث عن الملفّات على Linux


محمد أحمد العيل

يُواجه الكثير من مستخدمي Linux الجدُد مشكلة العثور على الملفّات الّتي يبحثون عنها على أجهزتهم. يَعرض هذا الدّرس لكيفيّة استخدام أمر find، ممّا يُساعد في البحث عن الملفّات على Linux عن طريق مُرْشِحات Filters ومُعاملات عدّة. سنتطرّق أيضًا لأمر locate وهو طريقة أخرى للبحث عن الملفّات.

البحث عن ملفّ باسمه

الطّريقة البديهيّة للبحث عن الملفّات هي استخدام أسمائها. للعثور على ملفّ باسمه أدخِل الأمر التّالي:

find -name query

حيث query هي عبارة البحث، الّذي سيفرّق عند استخدام خيّار name- بين حالة الأحرف (كبيرة Upper case أو صغيرة Lower case). يعني هذا أنّ البحث عن file سيُعطي نتائج مختلفة عن البحث عن File.

ملحوظة: عند عدم ذكر مجلّد للبحث فيه، فإنّ أمر find يبحث في مجلّد العمل.

للبحث عن ملفّ باسمه دون أخذ حالة الأحرف في الحسبان نستخدِم خيّار iname-.

find -iname query

إن كنت تريد العثور على كل الملفّات الّتي لا تُوافق نمطًا Pattern مُحدّدًا، يُمكنك عكس البحث باستخدام ! أو not-. في حال استخدام ! فيجب تخليصها Escape حتّى لا يُحاول سطرُ الأمر تفسيرها قبل بدْء عمل find.

find -not -name query_to_avoid

أو

find \! -name query_to_avoid

حيثُ query_to_avoid هي عبارة البحث الّتي نُريد تجنب وجودها في اسم الملفّ.

العثور على ملفّ بنوعه Type

توجد أيضًا إمكانيّة البحث عن ملفّات حسب نوعها. يُستخدَم خيّار type-. آليّة العمل هي كالتّالي:

find -type type_descriptor query

حيث type_descriptor مُعطًى يصِف نوع الملفّ. يُمكن أن يأخذ هذا المُعطى القيّم التّاليّة:

  • f: ملفّ عادي،

  • d: مُجلّد،

  • l: وصلة رمزيّة،

  • c: جهاز مِحرفي Character device،

  • b: جهاز كُتلي Block device.

يبحث الأمر التّالي، مثلًا، عن كلّ الأجهزة المِحرفيّة الموجودة في النّظام:

find / -type c

مثال على النّتيجة:

/dev/parport0
/dev/snd/seq
/dev/snd/timer
/dev/autofs
/dev/cpu/microcode
/dev/vcsa7
/dev/vcs7
/dev/vcsa6
/dev/vcs6
/dev/vcsa5
/dev/vcs5
/dev/vcsa4
. . .

إذا أردنا البحث عن كلّ الملفّات ذات اللّاحقة conf. فيُمكننا ذلك باستخدام الأمر:

find / -type f -name *.conf

ملحوظة: في الأمر السّابق حدّدنا مكان البحث بالمجلّد الجذر /. إن أردنا أن يكون البحث مقتصِرًا على مجلّد معيَّن نُضيف مساره مباشرةً بعد الأمر.
النّتيجة:

/var/lib/ucf/cache/:etc:rsyslog.d:50-default.conf
/usr/share/base-files/nsswitch.conf
/usr/share/initramfs-tools/event-driven/upstart-jobs/mountall.conf
/usr/share/rsyslog/50-default.conf
/usr/share/adduser/adduser.conf
/usr/share/davfs2/davfs2.conf
/usr/share/debconf/debconf.conf
/usr/share/doc/apt-utils/examples/apt-ftparchive.conf
. . .

ترشيح المُخرجات حسب التّاريخ والحجم

يُتيح أمر find ترشيح النّتائج حسب التاريخ والحجم.

الحجم

يُستخدَم خيّار size- لترشيح نتائج البحث حسب الحجم. نُضيف لاحقة للقيمة المعطاة لتحديد الوحدة المُستخدَمة. في ما يلي بعض الخيّارات المُنتشرة:

  • c: بايت Byte،
  • k: كيلوبايت Kilobytes،
  • M: ميغابايت Megabytes،
  • G: غيغابايت Gigabytes،
  • b: كتلة بحجم 512 بايت.

للبحث عن كلّ الملفّات ذات الحجم المُساوي ل50 بايت بالضّبط:

find / -size 50c

للبحث عن الملفّات الّتي يقلّ حجمها عن 50 بايت نستخدم الصّيغة التّاليّة (لاحظ علامة - أمام 50c ):

find / -size -50c

بالنّسبة للملفّات ذات الحجم الأكبر من 700 ميغابايت فالأمر يكون على النّحو التّالي (لاحِظ علامة +):

find / -size +700M

التّاريخ

يُخزِّن لينوكس بياناتٍ عن تواريخ الوصول Access time، تواريخ التّعديل Modification وتواريخ التّبديل Change:

  • تاريخ الوصول: آخر مرّة قُرئ من الملفّ أو كُتب فيه.
  • تاريخ التّعديل: آخر مرّة عُدِّل فيها على محتوى الملفّ.
  • تاريخ التّبديل: آخر مرّة غُيّرت فيها البيانات الوصفيّة Meta-data المُتعلّقة بوضع الملفّ ضمن نظام الملفّات.

تُوفّر خيّارات atime ، -mtime-، وctime- إمكانيّة ترشيح نتائج البحث حسب هذه التّواريخ. ولتحديدٍ أدقّ نستخدم علامتيْ + و- الّلتان تعنيان على التّوالي قبل وبعد. تُمثّل قيمة هذه المعطيات عدد الأيّام التي نُريد البحث فيها.

الأمر التّالي يبحث عن الملفّات الّتي عُدِّل على محتواها في آخر يوم:

find / -mtime 1

إن أردنا البحث عن الملفّات المقروءة في مدّة أقلّ من يوم ننفّذ الأمر التّالي (الملفّات المقروءة منذ يوم بالضّبط لن تظهر في النّتائج):

find / -atime -1

للبحث عن الملفّات الّتي غُيّر في بياناتها الوصفيّة قبل ثلاثة أيّام (الملفّات المُغيّر فيها قبل يوم أو اثنين لن تظهر في النّتائج):

find / -ctime +3

توجد أيضًا خيّارات بديلة للبحث حسب الدّقائق وليس الأيّام:

find / -mmin -1

يبحث الأمر أعلاه عن الملفّات الّتي عُدِّل على محتواها في آخر دقيقة.

يُمكِن أيضًا أخذُ ملفّ آخر مرجعًا للمقارنة على أساسه. الأمر التّالي يبحث عن الملفّات الأجدد (خيّار newer-) من ملف باسم myfile.

find / -newer myfile

البحث عن ملفّات باسم المالِك والأذون Permission

توجد أيضًا إمكانيّة البحث عن الملفّات باسم مالكها أو مجموعة المستخدِمين الّتي ينتمي إليها المالك عن طريق الخيّارين user- وgroup- على التّوالي.

الأمر التّالي يبحث عن الملفّات الّتي يملكهاالمستخدِم syslog:

find / -user syslog

بطريقة مُشابهة نبحث عن الملفّات الّتي ينتمي مالكها لمجموعة shadow:

find / -group shadow

بالنّسبة للبحث اعتمادًا على أذون الملفّات فالشّكل العام هوّ التّالي:

find / -perm 644

يبحث الأمر أعلاه عن الملفّات الّتي ضُبِطت أذونها على 644.

إن أردنا البحث عن الملفّات بأذون تشمل على الأقل الأذون السّابقة ننفّذ الأمر التّالي (لاحِظ علامة - أمام الأذون):

find / -perm -644

سينتُج عن هذا الأمر عرضُ كلّ الملفّات الّتي لديها أذون 644 والملفّات ذات الأذون الإضافية. مثلًا، سيظهر ضمن النّتائج ملفّ بأذون 744.

ترشيح المُخرجات حسب الموقع في نظام الملفّات

سننشئ في هذه الفقرة بنية مجلّدات ضمن مجلّد مؤقّت. ستشتمل هذه البنية على ثلاث مستويات، يوجد في المستوى الأوّل منها عشر مجلَّدات. سيحوي كلّ واحد من هذه المجلّدات (بما فيها المجلّد المؤقَّت الّذي سنسمّيه test) عشر ملفّات وعشر مجلّدات.

أنشِئ بنية الملفّات هذه بتنفيذ الأوامر التّاليّة:

cd
mkdir -p ~/test/level1dir{1..10}/level2dir{1..10}/level3dir{1..10}
touch ~/test/{file{1..10},level1dir{1..10}/{file{1..10},level2dir{1..10}/{file{1..10},level3dir{1..10}/file{1..10}}}}
cd ~/test

يمكنك التّأكّد من بنية المجلّدات باستخدام أوامر ls وcd. تأكّد من العودة إلى المجلّد test قبل تنفيذ الأوامر المقبلة.

cd ~/test

سنعمل على الحصول على ملفّات محدّدَة ضمن ينسة الملفّات هذه. فلنبدأ عن ملفّ باسمه:

find -name file1

النّتيجة:

./level1dir7/level2dir8/level3dir9/file1
./level1dir7/level2dir8/level3dir3/file1
./level1dir7/level2dir8/level3dir4/file1
./level1dir7/level2dir8/level3dir1/file1
./level1dir7/level2dir8/level3dir8/file1
./level1dir7/level2dir8/level3dir7/file1
./level1dir7/level2dir8/level3dir2/file1
./level1dir7/level2dir8/level3dir6/file1
./level1dir7/level2dir8/level3dir5/file1
./level1dir7/level2dir8/file1
. . .

توجد الكثير من النّتائج. فلنجرِّب عدَّ نتائج الأمر أعلاه:

find -name file1 | wc -l

النّتيجة:

1111

توجد - إذن - ملفّات عديدة. سنُحاول في ما يلي الاقتصار على بعضها.


يُحدّد الأمر التّالي المستوى الأعلى الّذي يصله الأمر بحثًا عن الملفّات، وذلك انطلاقًا من مجلّد البحث.

find -maxdepth num -name query

للبحث عن الملفّات باسم file1 الموجودة فقط في المجلّدات الّتي تبدأ أسماؤها بـlevel1 يُمكن تحديد المستوى الثّاني بوصفه العمقَ الأقصى (مجلّد البحث هو المستوى الأوّل، level1 هو المستوى الثّاني):

find -maxdepth 2 -name file1

النّتيجة:

./level1dir7/file1
./level1dir1/file1
./level1dir3/file1
./level1dir8/file1
./level1dir6/file1
./file1
./level1dir2/file1
./level1dir9/file1
./level1dir4/file1
./level1dir5/file1
./level1dir10/file1

قائمة أخفّ كثيرًا من قائمة الملفّات السّابقة.

يُمكِن أيضًا تحديد مستوى أدنى بحيثُ تُتَجاهل المجلّدات الموجودة في مستوى لا يصِل للمستوى الأدنى المُحدَّد.

find -mindepth num -name query

في المثال التّالي نبحث عن ملفّات باسم file1 ضمن المستوى الرّابع وما يليه (المستوى الخامس، السّادس …إلخ). في بنية الملفّات الّتي أنشأناها يوجد آخر مجلّد ضمن المستوى الرّابع، وهو ما يعني أنّنا هنا نبحث عن ملفّات في المستوى الأخير من بنية المجلّدات المعنيّة.

find -mindepth 4 -name file1

النّتيجة:

./level1dir7/level2dir8/level3dir9/file1
./level1dir7/level2dir8/level3dir3/file1
./level1dir7/level2dir8/level3dir4/file1
./level1dir7/level2dir8/level3dir1/file1
./level1dir7/level2dir8/level3dir8/file1
./level1dir7/level2dir8/level3dir7/file1
./level1dir7/level2dir8/level3dir2/file1
. . .

حصلنا مجدّدًا على الكثير من الملفّات (1000).

يُمكن دمجُ خيّاريْ mindepth- وmaxdepth- لحَصر النّتائج ضمن مستويات معيَّنة.
نحدّد في الأمر التّالي المستوى الأدنى mindepth- والمستوى الأقصى mindepth- للبحث عن الملفّات:

find -mindepth 2 -maxdepth 3 -name file1

النّتيجة:

./level1dir7/level2dir8/file1
./level1dir7/level2dir5/file1
./level1dir7/level2dir7/file1
./level1dir7/level2dir2/file1
./level1dir7/level2dir10/file1
./level1dir7/level2dir6/file1
./level1dir7/level2dir3/file1
./level1dir7/level2dir4/file1
./level1dir7/file1
. . .

تنفيذ وتجميع أوامر find

يُتيح أمر find إمكانيّة تنفيذ أوامر على نتائج البحث مباشرةً عن طريق مُعطَى exec-. آليّة العمل هي:

find find_parameters -exec command_and_params {} \;

حيثُ find_parameters تُمثّل خيّارات البحث وcommand_and_params الأمر المُراد تنفيذه على نتيجة البحث. علامة {} هي ماسك مكان Placeholder تحلّ محلَّ الملفّات المُطابقة لخيارات البحث. تُشير علامة ;\ إلى نهاية الأمر.

يُمكن، على سبيل المثال، البحثُ عن ملفّات المجلَّدات السّابقة الّتي لديها أذون 644 وتعديلها إلى 664.

cd ~/test
find . -perm 644 -exec chmod 664 {} \;

الأمر التّالي يُعدِّل أذون مجلَّد العمل (يُشار إليه بنقطة .):

find . -perm 755 -exec chmod 700 {} \;

إذا أردنا تجميع عدّة خيارات بحث فيُمكن استخدام أوامر and أو or لهذا الغرض. تعني and أنّ نتيجة البحث يجب أن تُطابق خيّارات البحث كلّها، أمّا or فتعني أنّ نتيجة البحث يكفي أن تُوافق أحد الخيارات. عند إضافة أكثر من خيار وعدم ذكر طريقة التّجميع (and أو or) فإنّ find تُطبّق and في هذه الحالة.

find . -name file1 -or -name file9

البحث عن ملفّات باستخدام locate

أمر Locate هو طريقة بديلة وأسرع - في الغالب- للبحث عن الملفّات، حيثُ يمكنه البحث في كامل ملفّات النّظام بكلّ يُسر؛ إلّا أنّه يُقدِّم خيّارات أقّل من تلك الّتي يُوفّرها أمر find.

قدتحتاج لتثبيت حزمة mlocate من أجل استخدام أمر locate:

sudo apt-get update
sudo apt-get install mlocate

السّبب وراء كون locate أسرَع من find هوّ أنّه يعتمد على قاعدة بيانات تخزّن بيانات الملفّات الموجودة في النّظام.
تُحدَّث قاعدة البيانات هذه عادةً تلقائيًّا مرةً في اليوم، ولكن يُمكن أيضًا تحديثُها يدويًّا عن طريق الأمرupdatedb:

sudo updatedb

نفِّذ هذا الأمر الآن وتذكّر أنّ قاعدة بيانات locate يجب أن تكون مُحدَّثَة حتى تضمن ظهور الملفّات المنشأة أو المنقولة حديثًا في نتائج البحث.
صيغة البحث عن ملفّات باستخدام locate هي التّاليّة:

locate query

حيث query تُمثّل عبارة البحث.

يُتيح أمر locate إمكانيّة ترشيح نتائج البحث.
نستخدم خيّار b- سبيل المثال، للبحث عن الملفّات الّتي توجد عبارة البحث في أسمائها؛ بدلًا من البحث عن كلّ ملفّ توجد عبارة البحث في المسار المؤدّي إليه، الّذي هو الإعداد الافتراضي:

locate -b query

يُعرَف اسم الملفّ بالاسم القاعدي Basename لتمييزه عن الاسم الكامل للملفّ الّذي يتضمّن مساره.

يوجد أيضًا خيّار e- لقصر نتائج البحث على الملفّات الموجودة فعلًا على النّظام؛ أي تلك الّتي لم تُحذَف منذ آخر تحديث لقاعدة البيانات عبر الأمر updatedb.

locate -e query

استخدِم خيار S- لعرض إحصاءات عن المعلومات الّتي تُخزّنها قاعدة بيانات locate:

locate -S

مثال على النّتيجة:

Database /var/lib/mlocate/mlocate.db:
    3,315 directories
    37,228 files
    1,504,439 bytes in file names
    594,851 bytes used to store database

خاتمة

يُعدّ أمرا find وlocate طرقتيْن جيّدتَيْن للبحث عن الملفّات الموجودة على النِّظام. يرجع إليك قرار استخدام أيّ من الأداتيْن. يُمكن الرّفع من إمكانيّات الأداتيْن عبر تمرير مُخرجاتهما إلى أوامر أخرى مثل sort ،wc وgrep.

ترجمة - وبتصرّف - لمقال How To Use Find and Locate to Search for Files on a Linux VPS.





تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن