חידת יוניקס
פוסט זה כולל טיפ קצר על כלי עבודה בסביבת Linux. בשביל ללמוד יותר על עבודה בסביבת Linux ו Unix אני ממליץ לכם לבדוק את קורס Linux שיש לנו כאן באתר. הקורס כולל מעל 50 שיעורי וידאו והמון תרגול מעשי ומתאים גם למתחילים.
את החידה הבאה לקח לי הרבה יותר מדי זמן לפתור (כמעט שעה). נסו אתם וספרו בתגובות אם הייתם יותר זריזים ממני.
1. המשימה
נתונה הרשימה הבאה של אלבומי החיפושיות, אבל חלק משמות האלבומים מופיעים מספר פעמים. הדפיסו שם כל אלבום פעם אחת בלבד בלי לשנות את סדר השורות (ובלי להשתמש בכלים שכבר כוללים מימוש למילון כמו פרל, רובי או awk):
Please Please Me
With the Beatles
A Hard Day's Night
Beatles for Sale
With the Beatles
Help!
Rubber Soul
Beatles for Sale
Revolver
Help!
Sgt. Pepper's Lonely Hearts Club Band
Beatles for Sale
Sgt. Pepper's Lonely Hearts Club Band
Help!
Magical Mystery Tour
The White Album
Abbey Road
The White Album
2. פתרון
הדרך הקלה היא כמובן לקחת שפת תכנות שכבר יודעת לעבוד עם מילונים כגון פרל, רובי, awk או אפילו bash החל מגירסא 4. לא צריך יותר מרגע בשביל להגיע לשורת הפרל הבאה:
cat albums | perl -ne 'print unless $h{$_}++'
או ברובי:
cat albums | ruby -e 'puts STDIN.readlines.uniq'
אבל האם אפשר לבצע את אותה הפעולה בלי להשתמש בכלים שכבר כוללים את הפונקציונאליות הזאת מובנית? התשובה כן, אבל זה קצת פחות מובן מאליו. הטריק הוא להוסיף מזהה יחודי לכל שורה שנוכל למיין לפיו בהמשך, למשל מספרי שורות:
cat -n albums | sort -k 2 -u | sort -k 1
והפלט:
1 Please Please Me
2 With the Beatles
3 A Hard Day's Night
4 Beatles for Sale
6 Help!
7 Rubber Soul
9 Revolver
11 Sgt. Pepper's Lonely Hearts Club Band
15 Magical Mystery Tour
16 The White Album
17 Abbey Road
מיטיבי הלכת יוסיפו cut כדי להיפטר ממספרי השורות ולחזור לפורמט הקלט המקורי:
cat -n albums | sort -k 2 -u | sort -k 1 | cut -f2-