הקדמה
כלי Linux בדרך כלל מתאפיינים בפילוסופיה של יוניקס לעיצוב. מודעים לשימוש בכלים קטנים, בשימוש בקבצי טקסט פשוטים כקלט וכפלט, ולפעול באופן מודולרי. כתוצאה ממנה, יש לנו פונקציות עיבוד טקסט מעולות עם כלים כמו sed ו־awk
.
awk
הוא גם שפת תכנות ועובד טקסט שבאפשרותך להשתמש בו כדי לעבד נתוני טקסט בדרכים מאוד שימושיות. במדריך זה, תלמד כיצד להשתמש בכלי השורת פקודה awk
וכיצד להשתמש בו לעיבוד טקסט.
תחביר בסיסי
פקודת awk
כלולה כבר במערכות Linux המודרניות בצורה ברירת מחדל, לכן אין צורך להתקין אותה כדי להתחיל להשתמש בה.
awk
היא הכי שימושית כאשר מתמודדים עם קבצי טקסט המסודרים בדרך צפויה. למשל, היא מצוינת בפענוח ובעיבוד של נתונים טבלאיים. היא פועלת על בסיס שורה-אחר-שורה ועוברת דרך כל הקובץ.
באופן ברירת המחדל, היא משתמשת ברווחים (רווחים, טאבים, וכו') כדי להפריד שדות. מזל שרבים מקבצי התצורה במערכת ה־Linux שלך משתמשים בתבנית זו.
הפורמט הבסיסי של פקודת awk
הוא:
ניתן להתעלם מחלק החיפוש או מחלק הפעולה בפקודת awk
. ברירת המחדל היא להדפיס את כל השורות המתאימות.
אם חלק החיפוש אינו נתון, awk
מבצע את הפעולה הרשומה על כל שורה.
אם שניהם נתונים, awk
משתמש בחלק החיפוש כדי להחליט האם השורה הנוכחית מתאימה לתבנית, ואז מבצע את הפעולות על התאמות.
בפורמט הכי פשוט שלה, אפשר להשתמש ב־awk
כמו ב־cat
כדי להדפיס את כל השורות של קובץ טקסט למסך.
צור קובץ favorite_food.txt
שמפרט את המאכלים המועדפים של קבוצת חברים.
כעת השתמש בפקודת awk
כדי להדפיס את הקובץ למסך.
תראה את הקובץ מודפס למסך.
Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica
זה לא מאוד שימושי. בוא ננסה את יכולות הסינון של awk
על ידי חיפוש בקובץ לטקסט "חול".
Outputcarrot sandy
sandwich brian
כפי שתראה, awk
מדפיס כעת רק את השורות שיש בהם את התווים "חול".
באמצעות ביטויים רגולריים, אפשר לכוון חלקים ספציפיים של הטקסט. כדי להציג רק את השורה שמתחילה באותיות "חול", השתמש בביטוי הרגולרי ^חול
:
הפעם, מוצגת רק שורה אחת:
Outputsandwich brian
באופן דומה, אפשר להשתמש בחלק הפעולה כדי לציין אילו חלקי מידע אתה רוצה להדפיס. לדוגמה, כדי להדפיס רק את העמודה הראשונה, השתמש בפקודה הבאה:
Outputsandwich
ניתן להתייחס לכל עמודה (כפי שמופרדת על ידי רווחים) על ידי משתנים המשוייכים למספר העמודה שלהן. לדוגמה, העמודה הראשונה היא $1
, השנייה היא $2
, ואפשר להתייחס לכל השורה באמצעות $0
.
משתנים פנימיים ותבנית מורחבת
הפקודה awk
משתמשת במשתנים פנימיים כדי להקצות מידע מסוים בעת עיבוד קובץ.
המשתנים הפנימיים שהפקודה awk
משתמשת בהם הם:
- FILENAME: מתייחס לקובץ הקלט הנוכחי.
- FNR: מתייחס למספר הרשומה הנוכחית יחסית לקובץ הקלט הנוכחי. לדוגמה, אם יש לך שני קבצי קלט, זה יגיד לך את מספר הרשומה של כל קובץ בנפרד במקום כסכום.
- FS: המפריד הנוכחי שמשמש לציון כל שדה ברשומה. כברירת מחדל, הוא מוגדר לרווחים.
- NF: מספר השדות ברשומה הנוכחית.
- NR: מספר הרשומה הנוכחית.
- OFS: מפריד השדות למידע המוצג. לדוגמה, ברירת המחדל היא רווחים.
- ORS: מפריד הרשומות למידע המוצג. לדוגמה, ברירת המחדל היא תו חדש שורה.
- RS: המפריד רשומות שמשמש להבחנה בין רשומות נפרדות בקובץ הקלט. בדרך כלל, זהו תו שורה חדשה.
ניתן לשנות את ערכי המשתנים הללו כרצונך כדי להתאים אותם לצרכי הקבצים שלך. בדרך כלל אתה עושה זאת בשלב האתחול של עיבודך.
זה מביא אותנו לעקרון חשוב נוסף. תחביר ה־awk
קצת יותר מורכב ממה שהשתמשת בו עד כה. ישנם גם בלוקי BEGIN
ו־END
אופציונליים שיכולים להכיל פקודות לביצוע לפני ואחרי עיבוד הקובץ, בהתאמה.
זה משנה את תחביר השפה הרחב שלנו למשהו דומה לזה:
המילים המפתח BEGIN
ו־END
הן קבוצות תנאים ספציפיות, בדומה לפרמטרי החיפוש. הן מתאימות לפני ואחרי שהמסמך עבר עיבוד.
זה אומר שתוכל לשנות חלק מהמשתנים הפנימיים בקטע ה־BEGIN
. לדוגמה, קובץ ה־/etc/passwd
מופרד בין שדותיו על ידי נקודות שבירה (:
) במקום רווח לבן.
כדי להדפיס את העמודה הראשונה של קובץ זה, הרץ את הפקודה הבאה:
Outputroot
daemon
bin
sys
sync
games
man
. . .
ניתן להשתמש בבלוקי BEGIN
ו־END
כדי להדפיס מידע אודות השדות שאתה מדפיס. השתמש בפקודה הבאה כדי להמיר את הנתונים מהקובץ לטבלה, מסודרת לפי טאבים באמצעות \t
:
תראה את הפלט הזה:
OutputUser UID GID Home Shell
--------------
root 0 0 /root /bin/bash
daemon 1 1 /usr/sbin /bin/sh
bin 2 2 /bin /bin/sh
sys 3 3 /dev /bin/sh
sync 4 65534 /bin /bin/sync
. . .
---------
File Complete
כפי שניתן לראות, ניתן לפורמט דברים באופן נעים על ידי השימוש בתכונות של awk
.
כל אחת מהאזורים המורחבים אופציונליים. למעשה, האזור העיקרי לפעולה עצמו הוא אופציונלי אם נגדיר אזור אחר. לדוגמה, ניתן לעשות דברים כמו כן:
ותראו פלט זה:
OutputWe can use awk like the echo command
כעת נסתכל על איך לחפש טקסט בתוך שדות של הפלט.
חיפוש שדות וביטויים מורכבים
באחת מהדוגמאות הקודמות, הדפסת את השורה בקובץ favorite_food.txt
שהתחילה ב-"sand". הייתה זו משימה קלה מאחר וחיפשת את תחילת השורה כולה.
מה קורה אם ברצונך לגלות האם דפוס החיפוש התואם תחילת שדה במקום?
יצירת גרסה חדשה של קובץ favorite_food.txt
שמוסיפה מספר פריט לפני אוכל כל אדם:
אם ברצונך למצוא את כל המזונות מתוך קובץ זה שמתחילים ב-"sa", תוכל לנסות משהו דומה לזה:
זה מציג את כל השורות שמכילות "sa":
Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
כאן, אתה מתאים לכל הופעה של "sa" במילה. זה כולל דברים כמו "ווסאבי" שיש לה את הדפוס באמצע, או "סנדי" שאינו בעמודה שבה ברצונך. במקרה זה אתה רק מעוניין במילים שמתחילות ב-"sa" ב- עמוד ה-שני.
ניתן להגדיר ל־awk
לחפש רק בתחילת העמוד השני באמצעות הפקודה הזו:
כפי שניתן לראות, זה מאפשר לנו לחפש רק בתחילת העמוד השני עבור התאמה.
חלק ה־field_num ~
מציין כי awk
צריך להתייחס רק לעמודה השנייה.
Output3 sandwich brian
4 salad ryan
ניתן בקלות לחפש גם אחר דברים שאינם מתאימים על ידי כלול התו "!" לפני הטילדה (~). הפקודה הזו תחזיר את כל השורות שאין להן מזון שמתחיל ב־"sa":
Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica
אם תחליטו מאוחר יותר שאתם רק מעוניינים בשורות שאינן מתחילות ב־"sa" ומספר הפריט הוא פחות מ־5, תוכלו להשתמש בביטוי מורכב כמו זה:
הפקודה מציגה מספר רעיונות חדשים. הראשון הוא היכולת להוסיף דרישות נוספות עבור התאמה של השורה באמצעות האופרטור &&
. באמצעות זאת, ניתן לשלב מספר של תנאים כדי שהשורה תותאם. במקרה זה, אתה משתמש באופרטור זה כדי להוסיף בדיקה שערך העמודה הראשונה קטן מ־5.
תראו את הפלט הזה:
Output1 carrot sandy
2 wasabi luke
ניתן להשתמש ב־awk
לעיבוד קבצים, אך ניתן גם לעבוד עם הפלט של תוכניות אחרות.
עיבוד הפלט מתוכניות אחרות
ניתן להשתמש בפקודת awk
כדי לפענח את פלט התוכניות האחרות במקום לציין שם קובץ. לדוגמה, ניתן להשתמש ב־awk
כדי לפענח את כתובת ה־IPv4 מהפקודה ip
.
הפקודה ip a
מציגה את כתובת ה־IP, כתובת השידור ומידע נוסף על כל ממשקי הרשת במחשב שלך. כדי להציג את המידע עבור הממשק הנקרא eth0
, השתמש בפקודה זו:
תראה את התוצאות הבאות:
Output2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
ניתן להשתמש ב־awk
כדי לגשת אל שורת ה־inet
ולאחר מכן להדפיס רק את כתובת ה־IP:
הדגל -F
אומר ל־awk
להפריד לפי נקודותיים לצדדים או רווחים באמצעות הביטוי הרגולרי [\/ ]+
. זה מפריד את השורה inet 172.17.0.11/16
לשדות נפרדים. כתובת ה־IP נמצאת בשדה השלישי מכיוון שהרווחים בתחילת השורה גם מחשבים כשדה, מאחר שהפרדת לפי רווחים וגם לפי נקודותיים. שים לב ש־awk
טיפל ברווחים רצופים כרווח יחיד במקרה זה.
הפלט מציג את כתובת ה־IP:
Output172.17.0.11
תמצא הרבה מקומות שבהם ניתן להשתמש ב־awk
כדי לחפש או לפענח את פלט של פקודות אחרות.
סיכום
עכשיו, אמור לך להבין באופן בסיסי כיצד ניתן להשתמש בפקודת awk
כדי לשנות, לעצב, ולהדפיס באופן בררת מחדל קבצי טקסט וזרמי טקסט. Awk הוא נושא רחב יותר, והוא למעשה שפת תכנות שלמה עם הקצאת משתנים, מבני בקרה, פונקציות מובנות, ועוד. ניתן להשתמש בו בתוך סקריפטים שלך כדי לעצב טקסט בדרך אמינה.
כדי ללמוד עוד על awk
, ניתן לקרוא את הספר החינמי בדומיין הציבורי של יוצריו שמסביר בפרטיות רבה יותר.