למצוא את הקסם

בעולם הלינוקס, יוניקס והמאק יש פקודה אחת בשורת הפקודה שמאוד מאוד מקלה על החיים והרבה אנשים פשוט לא יודעים לעבוד איתה נכון.

הפקודה הפשוטה, הנחמדה והשימושית הזו נקראת find. מה שאני כותב כאן תקף ללינוקס אבל בד"כ גם אפשרי באותה צורה גם במערכות אחרות, אבל לפעמים עם פרמטרים וחוקים מעט שונים, בשביל תוצאה זהה.

אז איך עובדים עם find ? ובכן הצורה המופשטת ביותר היא פשוט לכתוב את הפקודה כמו שהיא, כך שהיא תחזיר לנו רשימה של כל הקבצים והספריות במקום הנוכחי שלנו:

$ find

במידה ונרצה לחפש במקום אחר, נעשה את זה בצורה הבאה:

$ find /some/path

והחיפוש יתבצע על כל הקבצים והספריות בנתיב מסויים.

במידה ונרצה לחפש בכמה נתיבים בייחד עם בסיס משותף נוכל לעשות את זה בצורה הבאה:

$ find /some/{path,location,directory}

ואז החיפוש יתבצע גם בתת הספרייה path, גם בlocation וגם ב directory. שימו לב שהסוגריים המסולסלים שייכים ל bash ולא ל find והם מפורשים עבור find ל3 נתיבים שונים. כלומר זה מקביל ל:

$ find /some/path /some/location /some/directory

ניתן ככה גם לחפש בכמה נתיבים שונים לגמרי, אבל כאשר הבסיס הוא אחיד, אני ממליץ על השיטה של הסוגריים המסולסלים שחוסכת לנו כתיבה.

נגיד ונרצה לחפש רק מבנה מסויים של קבצים, נגיד קבצים שיש בהם את הצירוף test:

$ find /some/path -name "*test*"

הסיבה לגרשיים היא בשביל ש bash לא ינסה לפרש את הכוכביות למשהו שקשור אליו (לפעמים יכול להיות מצב שכזה), אלא יעביר אותם כמו שהם אל התוכנה.

במידה ונרצה לחפש ספרייה או סוג מאוד מדוייק של קובץ (לפי מערכת הקבצים של לינוקס/יוניקס ולא לפי סיומת) נשתמש בפקודה הבאה:

$ find /some/path -type d

ונקבל את כל רשימת הספריות היושבות תחת נתיב מסויים.

במידה ונרצה אבל לקבל רק את הספריות תחת אותו נתיב ללא תת הספריות שיש להן, נוכל להגביל את find בצורה הבאה:

$ find /some/path -type d -maxdepth 1

ועכשיו יש לנו רק את הספריות תחת הנתיב שביקשנו. במידה ונרצה אבל לקבל את הספריות ברמה ה 2 אבל לא יותר מ5 רמות בתוכן, נעשה את זה בצורה הבאה:

$ find /some/path -type d -maxdepth 5 -mindepth 2

נגיד ונרצה לקבל רק קבצים ששונו במהלך ה24 שעות אחרונות ומעלה נעשה את זה בצורה הבאה:

$ find /some/path -mtime +0

חשוב להבין קצת איך הזמנים האלו עובדים.

mtime עובד על n*24 אבל חשוב להבין משהו חשוב: 0 הוא לא 24*0 אלא 0 אומר רק 24 שעות. כלומר אפשר להגיד שזה יותר כמות הפעמים שנעשה 24+24 . כך שהספרה 1 היא בעצם 48 שעות.

עוד משהו שחשוב לדעת זה שכאשר רושמים רק מספר ללא סימן, אנחנו אומרים לfind למצוא רק ב24 שעות הנוכחיות, בעוד שבמידה ונוסיף את הסימן פלוס לפני המספר, נגיד לו שמטווח של 24 שעות ומעלה. ואם זה יהיה עם מינוס, אז עד 24 שעות ומטה. ככה זה עם כל סוגי הזמנים (מבחינת לוגיקה, לא מבחינת כמות שעות), גם אם מדובר בשניות או דקות.

עוד פעולה שתעזור לכם מאוד, זו האפשרות להריץ פקודה על כל דבר שנמצא באמצעות find ואנחנו נעשה את זה באמצעות הפקודה exec :

$ find /some/path -exec /bin/rm -rf {} \;

חשוב לשים לב לכמה פרטים:

  • כמו בכל האפשרויות האחרות, אפשר לשלב את כולם בשורה אחת (אלא אם כתוב בתעוד משהו אחר בנושא על אפשרות כלשהי)
  • סוגריים מסולסלים הם שם הקובץ המלא שהתקבל והם לא שייכים ל bash אלא ל find
  • הלוכסן ההפוך עם הנקודה פסיק צריכים להיות עם רווח מהפקודה/סוגריים מסולסלים, אחרת find יצעק על שגיאה ב exec
  • במידה וצריך יותר מפקודה אחת, אז צריך להוסיף עוד אפשרות של exec בהתאם לכמות הפקודות שצריך לבצע. לפעמים צריך לשים אותם לפי סדר מסויים אם אחת תשפיע על השנייה
  • אי אפשר להשתמש בפקודות bash אלא רק בתוכנות ממשיות. אני ממליץ להשתמש בנתיב המלא לפקודה, אך במידה והפקודה נמצאת במשתנה PATH לא חייבים.

עוד משהו חשוב שלפעמים צריך זה להדפיס נתונים על כל קובץ. ניתן להדפיס את שם הקובץ והנתיב שלו עם האפשרות print:

$ find /some/path -print

במידה ויש רצון להדפיס פרמטרים ספציפיים כמו נתוני state על הקובץ, תאריכים שונים ועוד, אפשר להשתמש באפשרות printf

$ find /some/path -printf "…."

יש ל find עוד המון יכולות ואפשרויות מחיפוש באמצעות ביטויים רגולריים (regex) ועד לצורת הרשאות. יש פשוט המון אפשרויות שלא תמיד חשבתם עליהם אבל כשתדעו עליהם, פתאום תראו עד כמה הפקודה מקלה על צורת העבודה שלכם ולכן מומלץ להמשיך ולילמוד על האפשרויות של find במסמך ה man של הפקודה.

11 מחשבות על “למצוא את הקסם

  1. נתנאל

    אני הכי אוהב את הפונקציה שמאפשרת ליצור רשימה של כל הקבצים שהשתנו ב־x הדקות האחרונות, שימושי במיוחד במרדף אחרי קובצי הגדרות:
    find . -mmin 1

  2. תומר

    אתה בטוח שהסינטקס של הסוגריים המסולסלים שלך נכון? בגלל שיש שם תווי רווח, bash יפרוס את זה ל־‎/some/path,‏ ‎./location ו־‎./directory ולא לאן שכתבת.

  3. תומר

    תיקון להודעה הקודמת שלי – תווי הרווח ישברו את הפריסה של bash. צריך לשים שם באקסלאש לפני הרווח…

    נתנאל – לא עדיף לשחק עם tail -f? ככה אתה גם מקבל את השינויים על המסך.

  4. ZooZ

    איבדת אותי ב"הרבה אנשים פשוט לא יודעים לעבוד איתה נכון".
    אם אני רוצה שיתנשאו עלי אני אלך לקרוא "הארץ".

  5. ik_5 מאת

    אם אתה חושב שזו התנשאות, אז יש לך בעיה רצינית יותר מאשר לעבוד עם find.

    הרבה אנשים עושים חלק גדול ממה שאני הדגמתי באמצעות pipe ותוכנות במקום לעבוד עם היכולות של הפקודה. אם אתה רוצה לעבוד ככה, אל תקרא.

  6. ZooZ

    עידו,

    אני מתנצל על התגובה הקודמת שלי. היא נכתבה תחת השפעת מצב רוח רע וכאב ראש קודחני במיוחד.

    היה טוב יותר אם הייתי קולט את מצב הרוח שלי ולא הייתי מגיב בכלל, סליחה.

  7. el.il

    למה צריך find כשיש את locate?
    במקרה מצאתי וידאו שמסביר איך להשתמש בשתי הפקודות. גיליתי ככה גם את catfish, שהוא GUI מעולה שתומך בfind ובlocate ועוד , וגיליתי גם שהרצת updatedb בתור רוט מאיצה פלאים את החיפוש של גנום – שמתבסס גם הוא על locate.

  8. ik_5 מאת

    אם אתה יודע במדויק מה אתה רוצה למצוא מחינת שמות קבצים או מבחינת נתיבים, אז locate יותר טוב בזכות מסד הנתונים שבו הוא עובד.

    העניין הוא אבל שכאשר אתה צריך משהו קצת יותר רציני (מה הקבצים ששונו אצלך בחודש האחרון למשל), אז locate לפחות עד כמה שאני יודע (אשמח לגלות אחרת) לא יודע לתת לך מענה.

    זה הכל תלוי מה אתה בדיוק צריך בחיפוש שלך.

כתיבת תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s