שלושה סקריפטים ראשונים ב nushell כדי ללמוד איך זה עובד
נו-של הוא סוג חדש של Shell, הוא כתוב ב rust ומביא את הגישה של Powershell - לפיה כל דבר הוא data - גם ליוניקס. בואו נכתוב שלושה סקריפטים ראשונים ב nushell כדי ללמוד איך זה עובד ולחשוב אם הוא מתאים.
1. הצגת טקסט על ערך מויקיפדיה
את nushell אפשר להתקין לפי ההוראות באתר שלהם:
הכי קל באמצעות הפעלת:
brew install nushell
אחרי ההתקנה מפעילים nu
כדי להיכנס ל Shell ומספיק להפעיל ls
כדי להבין שאנחנו כבר לא בקנזס. זה הפלט:
ls 27/03/24 18:00:15
╭───┬───────────┬──────┬───────┬────────────────╮
│ # │ name │ type │ size │ modified │
├───┼───────────┼──────┼───────┼────────────────┤
│ 0 │ 02-one │ dir │ 64 B │ 2 hours ago │
│ 1 │ 03-two │ dir │ 64 B │ 2 hours ago │
│ 2 │ 04-three │ dir │ 64 B │ 2 hours ago │
│ 3 │ carlos.py │ file │ 643 B │ 35 minutes ago │
│ 4 │ clone.nu │ file │ 153 B │ 2 hours ago │
│ 5 │ inc.nu │ file │ 229 B │ an hour ago │
╰───┴───────────┴──────┴───────┴────────────────╯
סימן הקו אנכי מתפקד פחות או יותר כמו שתפקד ב Shell-ים הקלאסיים, אבל עכשיו בגלל שהכל הוא data הרבה יותר קל לעבוד עם המידע, לדוגמה בשביל להדפיס רק את שם הקובץ והגודל נכתוב:
ls | select name size
╭───┬────────────────────────┬───────────╮
│ # │ name │ size │
├───┼────────────────────────┼───────────┤
│ 0 │ 03-one │ 64 B │
│ 1 │ 04-two │ 64 B │
│ 2 │ 05-three │ 64 B │
│ 3 │ career-craft-ai-bg.jpg │ 225.3 KiB │
│ 4 │ clone.nu │ 153 B │
│ 5 │ inc.nu │ 229 B │
│ 6 │ text.txt │ 82 B │
│ 7 │ wiki.nu │ 239 B │
╰───┴────────────────────────┴───────────╯
סקריפט ב nushell מסתיים בסיומת nu. לא הצלחתי להתקין את התוסף ל vim שלהם אבל התוסף ל VS Code עבד לי מצוין. כמו שהבטחתי שלושה סקריפטים בשביל התחלה, הראשון מקבל שם של ערך מויקיפדיה ומציג את התוכן:
def main [value] {
let url = $"https://en.wikipedia.org/w/api.php?action=query&prop=revisions&titles=($value)&rvslots=*&rvprop=content&formatversion=2&format=json"
http get $url | get query.pages.0.revisions.0.slots.main.content
}
איך זה עובד? אז סיפרתי כבר שכל דבר זה Data, ולכן גם JSON שמגיע מהרשת הוא מידע שאפשר לעבוד איתו. הפקודה http get פונה לרשת למשוך מידע והפקודה get מציגה רק חלק מהטבלה. במקרה של ויקיפדיה ה JSON מכיל אוביקטים מקוננים והמחרוזת:
query.pages.0.revisions.0.slots.main.content
היא הנתיב בתוך האוביקט שמכיל את הערך. אם תתקינו nushell ותשמרו את הסקריפט בקובץ בשם wiki.nu תוכלו להפעיל אותו באופן הבא כדי להציג ערך מתוך ויקיפדיה:
nu wiki.nu Pet_door
2. שינוי שם של כל הקבצים שמתחילים במספר
אתגר שני שרציתי לנסות בשביל ללמוד על nushell היה לשנות את השמות של כל הקבצים ששמם מתחיל במספר באמצעות העלאת המספר ב-1, כלומר אם היו לי בתיקיה הקבצים:
ls [0-9]*
27/03/24 18:07:58
╭───┬──────────┬──────┬──────┬─────────────╮
│ # │ name │ type │ size │ modified │
├───┼──────────┼──────┼──────┼─────────────┤
│ 0 │ 02-one │ dir │ 64 B │ 2 hours ago │
│ 1 │ 03-two │ dir │ 64 B │ 2 hours ago │
│ 2 │ 04-three │ dir │ 64 B │ 2 hours ago │
╰───┴──────────┴──────┴──────┴─────────────╯
אז אחרי הפעלת הסקריפט אני מקבל:
ls [0-9]*
╭───┬──────────┬──────┬──────┬─────────────╮
│ # │ name │ type │ size │ modified │
├───┼──────────┼──────┼──────┼─────────────┤
│ 0 │ 03-one │ dir │ 64 B │ 2 hours ago │
│ 1 │ 04-two │ dir │ 64 B │ 2 hours ago │
│ 2 │ 05-three │ dir │ 64 B │ 2 hours ago │
╰───┴──────────┴──────┴──────┴─────────────╯
וקוד הסקריפט:
for f in (ls [0-9]* | get name) {
let newname = $f | parse '{n}-{name}' | into int n | update n {|row| $row.n + 1 } | each {|row| [($row.n | fill -a right -c '0' -w 2), "-", $row.name] | str join } | get 0
mv $f $newname
}
נו זה מתחיל פשוט עם לולאת for, ואז מגיעה שורת המחץ - אני לוקח כל שם קובץ ומעביר אותו לפקודה מובנית בשפה שנקראת parse שמפענחת את המחרוזת לשני משתנים (במקרה שלי n ו name, עם מקף ביניהם). אחרי זה מתחילים לשחק עם המידע, הופכים את n למספר, מעלים אותו ב-1 ואז מחברים את כל העמודות למחרוזת אחת אותה אני שומר במשתנה newname
. שורה אחרונה של הלולאה היא ה mv שמשנה את שם הקובץ.
3. שכפול סקריפט לעצמו
עד לפה הייתי בטוח שהגעתי ל Shell שיודע לעשות הכל אבל אז הגיעה המשימה השלישית שם nushell קצת אכזב אותי. המטרה שלנו היא לכתוב סקריפט שמקבל בשורת הפקודה מספר שמות של קבצים ומעתיק את עצמו לקבצים ששמותיהם עברו כפרמטרים. הבעיה? ל nushell אין מקבילה למשתנה $0
של Shell-ים קלאסיים ולכן אני צריך להסתמך על זה שאני יודע מה שם הקובץ. בהנחה ששם הקובץ הוא clone.nu
הקוד הבא עובד:
def main [...destinations] {
let sourceFile = $env.FILE_PWD + "/clone.nu"
for output in $destinations {
cp $sourceFile $output
}
}
סך הכל nushell נראה כמו פרויקט מבטיח - הוא עובד מהר ועבודה עם מידע במקום עם טקסט יכולה לחסוך טעויות בתוכניות מורכבות.