בדף זה מובא הקוד של התוכנית ולאחריו פירוט שלו. #!/usr/local/bin/tclsh8.0 # Dos2Unix # Convert a file to Unix-style line endings # If the file is a directory, then recursively # convert all the files in the directory and below. # # Arguments # f The name of a file or directory. # # Side Effects: # Rewrites the file to have LF line-endings proc Dos2Unix {f} { puts $f if {[file isdirectory $f]} { foreach g [glob [file join $f *]] { Dos2Unix $g } } else { set in [open $f] set out [open $f.new w] fconfigure $out -translation lf puts -nonewline $out [read $in] close $out close $in file rename -force $f.new $f } } # Process each command-line argument foreach f $argv { Dos2Unix $f } הרצת התסריט #!/usr/local/bin/tclsh8.0 תחת מ"ה Unix שורה זו תגרום לקישור בין התסריט לפרשן ה Tcl. תחת Windows ניתן לשייך את הקבצים בעלי הסיומת "tcl" לתוכנית הפרשן וכך תמיד הם יורצו תחתיו. פרוצדורות ב Tcl החלק המרכזי בתוכנית הינה פרוצדורה בשם Dos2Unix. פרוצדורה זו דורשת ארגומנט אחד, f, שהוא שם ספריה או קובץ. proc Dos2Unix
{f} { הפרמטר f נקבע כאשר קרואם ל Dos2Unix בדוגמא שלהלן הוא מקבל את הערך myfile.txt: Dos2Unix myfile.txt ארגומנטים משורת הפקודה כאשר נרצה להריץ את התוכנית שלנו על ה Unix ייתכן ונרצה להעביר מספר ארגומנטים (שמות ספריות או קבצים) שהתוכנית שלנו תמיר. ארגומנטים שנתקבלו משורת ההרצה (CShell) נמצאים במשתנה argv. הפקודה foreach מבצעת לולאה על כל הארגומנטים ומפעילה את Dos2Unix על כל אחד מהם. foreach f $argv { בדיקת תנאים התוכנית שלנו מתייחסת באופן שונה לספריות וקבצים. אם הארגומנט הנוכחי הוא קובץ התוכנית תקרא אותו ותכתוב אותו לאחר המרת תוי סיום השורה. אם הארגומנט הוא ספריה שזי נרצה להמיר את כל הקבצים שהיא מכילה. שלם זה עלינו לבחון את סוג הארגומנט: if {[file
isdirectory $f]} { הפקודה if בודקת את תוצאת שיערוך ביטוי התנאי שבה. במקרה הזה הביטוי מכיל פקודת Tcl אחרת והיא file isdirectory, אשר מחזירה 1 אם הקובף הינו ספריה. הסוגריים המרובעים משמשים לשם תחימת הפקודה המקוננת. הסוגריים המסולסלים משמשים לקיבוץ חלקי הפקודה (החלק שיבוצע אם התנאי אמיתי והחלק שיבוצע אם שקרי). לולאה על רשימת ערכים במקרה של ספריה התוכנית Dos2Unix עוברת בלולאה על כל הקבצים שבספריה. הפקודה glob מחזירה רשימה של שמות קבצים המתאימים לתבנית שהיא קיבלה. התו * אומר שאין הגבלה על שמות הקבצים (חוקי הגדרת התבנית זהים לאלו שבחיפוש קבצים). שם הקובץ משורשר עם שם הספריה ללא תלות הפלטפורמה עליו אנחנו רצים. הפקודה file join, אשר משתמשת ב / , \ או : כמפרידים עבור Windows, Unix וגם Mac בהתאמה. לבסוף אנחנו רצים בלולאה על רשימת הקבצים שהחזירה glob: foreach g
[glob [file join $f *]] { בכל איטרציה של foreach הפרמטר g מקבל את הערך הבא ברשימת הערכים שהוחזרה ע"י glob. הדרך הפשוטה ביותר להמיר את הקבצים הינה לקרוא ל Dos2Unix באופן רקורסיבי. בקריאה רקרסיבית, מוקצה סט חדש של משתנים כך שלא תיווצר התנגשות או דריסה של ערכים בין קריאות שונות של Dos2Unix (רקורסיה סטנדרטית). עבודה עם קבצים בליבה של הפרוצדורה Dos2Unix נקרא קובץ לזכרון והוא נכתב מתוקן. ראשית עלינו לפתוח קובץ עם הפקודה open: set in [open
$f] הארגומנט הנוסף w גורם לקובץ להיפתח לכתיבה. אנו פותחים ערוצים אל הקבצים והם ישמשו אותנו לקריאה וכתיבה אליהם. אנו יכולים לפתוח שמות קבצים שונים עם הסיומת "new.". לכל קובץ מקור ייוצר קובץ מומר עם סיומת זו משורשרת שלמו המלא הקודם. כתיבה וקריאה מהקבצים מבוצעת ע"י שילוב פקודות: puts -nonewline $out [read $in] פקודה זו קוראת קובץ שלם אל הזכרון ומעבירה אותו לפקודה puts בשביל שתכתוב לפלט. ע"פ ברירת מחדל, puts תוסיף תוי סיום שורה (n/) לפלט שלה, אך אנו לא מעומינים בזאת ולכן נשתמש בדגל nonewline- על מנת לבטל התנהגות זאת. כאשר סיימנו עם הקבצים, עלינו לסגור את הערוצים אליהם. תוצר לוואי חשוב של פעולה זו הינה הבקשה המפורשות ממערכת ההפעלה לכתוב את התוצר שב out לדיסק. close $in
לבסוף עלינו לקרוא לקובץ החדש שיצרנו בשם של הקובץ המקורי ובכך למעשה לדרוס אותו. הדגל -force- נחוץ על מנת לא לתקוע את התוכנית שממתינה לאישור הדריסה ע"י file rename. file rename -force $f.new $f ייצוג סוף שורה בליבה של הפרוצדורה Dos2Unix נקרא קובץ לזכרון והוא נכתב חזרה ללא כל פעולה מיוחדת. Tcl מבצעת באופן אוטומטי את ההמרה של תוי סוף השורה. כאשר Tcl קוראת קובץ אל הזכרון היא מחליפה את כל תוי סוף הורה ב 'n/'. בזמן הכתיבה לפלט, Tcl ממירה את את הייצוג בזכרון בייצוג בטבעי של הפלטפורמה עליה היא רצה. כך יכולנו פשוט לקרוא קובץ ולכתוב אותו מחדש. במקרה שלנו הצורה בה נשמר הקובץ בזכרון היא זו שאנו מעוניינים בה ולכן איננו רוצים בהמרה. על מנת לבטל את ההמרה האוטומטית בפלט נכתוב file rename -force $f.new $f
|
< Dos2unix < דוגמאות
Dos2unix - קוד |
||||||||
|
|||||||||