טריק bash קטן שהציל לי את הקורס

פוסט זה כולל טיפ קצר על כלי עבודה בסביבת Linux. בשביל ללמוד יותר על עבודה בסביבת Linux ו Unix אני ממליץ לכם לבדוק את קורס Linux שיש לנו כאן באתר. הקורס כולל מעל 50 שיעורי וידאו והמון תרגול מעשי ומתאים גם למתחילים.
 

בשיעור על find בקורס Linux יש תרגיל שמבקש להוסיף סיומת קבועה לכל הקבצים בתיקיית תרגול מסוימת שיצרנו לטובת העניין. אבל מה קורה כשתלמיד מריץ בטעות את הפקודה מתיקיית הבית במקום מתיקיית התרגול?

1. הוספת סיומת קבועה

בשביל להוסיף סיומת קבועה לקבצים עם find משתמשים ב exec, למשל באופן הבא:

$ mkdir demo
$ cd demo
$ touch {a,b,c}.txt

$ find . -name '*.txt' -exec mv {} "{}".new

$ ls
a.txt.new b.txt.new c.txt.new

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

2. אל דאגה אני יודע bash

אין לי מושג איך למחוק סיומת משם הקובץ בתוך exec של find, אבל ב bash זה די פשוט. הלולאה הבאה הצילה את היום:

find . -print0 | while IFS= read -r -d $'\0' fname; do
    mv "$fname" "${fname%.new}"
done

היא רצה על כל הדברים ש find מוצא ומורידה מכל אחד מהם את הסיומת new.

3. וחידה לסיום

הקוד הבא מדפיס הודעה בכל פעם שמשנה שם קובץ אך לא ידפיס בסוף את מספר הקבצים הכולל ששמם שונה. יודעים למה? הסבירו בתגובות.

find . -print0 | while IFS= read -r -d $'\0' fname; do
    if mv "$fname" "${fname%.new}"; then
        echo "Renamed $fname -> ${fname%.new}"
        (( COUNT++ ))
    fi
done
echo "Total files changed: $COUNT"