דילוג לתוכן
ביטויים רגולריים

grep, sed ו־awk: חיפוש ועריכת טקסט מהטרמינל בלי לפחד מ־regex

שלוש פקודות קטנות בלינוקס — grep, sed ו־awk — פותרות כמות מפתיעה של משימות יומיומיות: למצוא שורה בקובץ לוג, להחליף טקסט בעשרות קבצים, לסכם עמודה מתוך CSV, לנקות פלט של פקודה אחרת, או לבדוק מהר אם משהו השתבש.

המאמר הזה הוא מדריך מעשי, לא סקירה תאורטית. נשתמש ב־bash על Linux/macOS, נכתוב ביטויים רגולריים שימושיים, נריץ דוגמאות מלאות, ונראה גם איפה נופלים בדרך. אם אתם בתחילת הדרך עם טרמינל, כדאי לעבור קודם על צעדים ראשונים; אם אתם מגיעים מעולם של פייתון, תגלו שחלק מהרעיונות דומים לעיבוד מחרוזות, רק שהכול קורה ישירות בשורת הפקודה.

מה כל כלי עושה, בקצרה

שלושת הכלים עובדים מצוין לבד, אבל הכוח האמיתי שלהם מגיע כשהם מתחברים בצינור פקודות עם |.

  • grep — מחפש שורות שמתאימות לתבנית. מתאים לשאלה: “איפה מופיע הטקסט הזה?”
  • sed — עורך זרם טקסט. מתאים להחלפות, מחיקות, הדפסה של טווח שורות, וניקוי פלט.
  • awk — מפרק שורות לשדות, מבצע חישובים, סינון וסיכומים. מתאים לקבצי CSV פשוטים, לוגים וטבלאות טקסט.

חשוב לזכור: לא כל בעיה חייבת להיפתר בשלושתם יחד. אם אתם רק מחפשים שורה, התחילו עם grep. אם צריך להחליף משהו, עברו ל־sed. אם יש עמודות, סכומים או תנאים לפי שדה — זה כבר אזור הנוחות של awk.

הכנה: קבצי תרגול בטוחים להרצה

הדוגמאות הבאות מיועדות ל־Linux/macOS עם bash. הן יוצרות תיקייה מקומית בשם textlab וקבצי דוגמה פשוטים. אין כאן סיסמאות, טוקנים או גישה לרשת.

bash
mkdir -p textlab

cat > textlab/access.log <<'EOF'
2026-10-26 09:00:01 GET / 200 18ms
2026-10-26 09:00:03 GET /api/users 200 42ms
2026-10-26 09:00:05 POST /api/login 401 37ms
2026-10-26 09:00:09 GET /missing-page 404 12ms
2026-10-26 09:01:11 GET /api/orders 500 88ms
2026-10-26 09:01:20 GET /assets/app.js 200 9ms
EOF

cat > textlab/users.csv <<'EOF'
id,name,email,role
1,Noa,[email protected],admin
2,Dan,[email protected],editor
3,Lea,[email protected],viewer
EOF

grep -nE ' (404|500) ' textlab/access.log

הפקודה האחרונה מחפשת בלוג שורות עם קוד סטטוס 404 או 500. הדגל -n מציג מספר שורה, והדגל -E מפעיל regex מורחב, כך שאפשר להשתמש ב־(404|500) בצורה קריאה.

הפלט הצפוי:

text
4:2026-10-26 09:00:09 GET /missing-page 404 12ms
5:2026-10-26 09:01:11 GET /api/orders 500 88ms

grep: למצוא בדיוק את השורות הנכונות

grep הוא הכלי הראשון שכדאי להכיר כשעובדים עם קבצי טקסט. הוא מחזיר שורות שמתאימות לתבנית. זו יכולה להיות מחרוזת רגילה כמו error, או ביטוי רגולרי מורכב יותר.

חיפוש פשוט לעומת חיפוש עם regex

חיפוש בסיסי:

bash
grep 'api' textlab/access.log

הפלט הצפוי:

text
2026-10-26 09:00:03 GET /api/users 200 42ms
2026-10-26 09:00:05 POST /api/login 401 37ms
2026-10-26 09:01:11 GET /api/orders 500 88ms

כאן אין צורך ב־regex מיוחד. אבל אם רוצים למצוא רק שורות שמתחילות בתאריך מסוים ומכילות בקשת GET, אפשר להשתמש ב־^, שמסמן תחילת שורה:

bash
grep -E '^2026-10-26 .* GET ' textlab/access.log

הפלט יכלול את שורות ה־GET בלבד מתוך אותו תאריך. הביטוי .* אומר “אפס או יותר תווים כלשהם”. זו תבנית נפוצה מאוד, אבל כדאי להשתמש בה בזהירות: היא רחבה, ולפעמים תופסת יותר ממה שהתכוונתם.

דגלים שימושיים של grep

דגל מה הוא עושה דוגמה
-n מציג מספרי שורות grep -n '500' file.log
-i מתעלם מאותיות גדולות/קטנות באנגלית grep -i 'error' file.log
-v מחזיר שורות שלא מתאימות grep -v '200' access.log
-r מחפש רקורסיבית בתיקיות grep -r 'TODO' src/
-E מפעיל ביטויים רגולריים מורחבים grep -E '404|500' access.log

sed: החלפה ועריכה בלי לפתוח עורך טקסט

sed קורא טקסט שורה אחר שורה ומפעיל עליו פקודות. השימוש הנפוץ ביותר הוא החלפה עם s/pattern/replacement/. האות s היא קיצור של substitute.

דוגמה מלאה: ניקוי כתובות אימייל בקובץ CSV

בדוגמה הבאה ניצור CSV, נחליף רווחים מיותרים אחרי פסיקים, ונשנה דומיין דוגמה מ־example.local ל־example.test.

bash
mkdir -p textlab

cat > textlab/contacts.csv <<'EOF'
id, name, email
1, Noa, [email protected]
2, Dan, [email protected]
3, Lea, [email protected]
EOF

sed -E 's/, +/,/g; s/@example\.local/@example.test/g' textlab/contacts.csv

הפקודה כוללת שתי החלפות: הראשונה מוחקת רווחים אחרי פסיקים, והשנייה מחליפה דומיין. הנקודה ב־example\.local מסומנת עם \, כי ב־regex נקודה רגילה פירושה “כל תו”.

הפלט הצפוי:

text
id,name,email
1,Noa,[email protected]
2,Dan,[email protected]
3,Lea,[email protected]

שמירה לקובץ חדש במקום עריכה במקום

אפשר לכתוב את הפלט לקובץ חדש עם >:

bash
sed -E 's/, +/,/g; s/@example\.local/@example.test/g' textlab/contacts.csv > textlab/contacts-clean.csv
cat textlab/contacts-clean.csv

זו דרך בטוחה יותר מאשר עריכה במקום, במיוחד כשאתם עדיין בודקים את הביטוי. קיימת אפשרות sed -i, אבל ההתנהגות שלה שונה מעט בין Linux ל־macOS. כשלא בטוחים, עדיף ליצור קובץ חדש, לבדוק אותו, ורק אז להחליף את המקורי אם צריך.

awk: עבודה עם עמודות, תנאים וסיכומים

awk חושב במונחים של רשומות ושדות. כברירת מחדל, כל שורה היא רשומה, וכל רצף רווחים מפריד בין שדות. בקבצי CSV פשוטים אפשר להגדיר מפריד עם -F,.

דוגמה מלאה: סיכום מכירות לפי מוצר

bash
mkdir -p textlab

cat > textlab/sales.csv <<'EOF'
date,product,amount
2026-10-26,book,3
2026-10-26,keyboard,1
2026-10-27,book,2
2026-10-27,mouse,4
2026-10-28,keyboard,2
EOF

awk -F, 'NR > 1 { total[$2] += $3 } END { for (product in total) print product, total[product] }' textlab/sales.csv | sort

כאן -F, מגדיר פסיק כמפריד. המשתנה NR הוא מספר השורה הנוכחית, ולכן NR > 1 מדלג על הכותרת. הביטוי total[$2] += $3 מסכם את העמודה השלישית לפי שם המוצר בעמודה השנייה.

הפלט הצפוי:

text
book 5
keyboard 3
mouse 4

מי שמכיר מילונים ב־פייתון יזהה כאן רעיון דומה: מפתח הוא שם המוצר, והערך הוא הסכום המצטבר.

שילוב פקודות: grep מסנן, sed מנקה, awk מסכם

לעיתים הכי נוח לבנות צינור בשלבים. קודם בודקים שכל פקודה עושה את חלקה, ורק אז מחברים. נניח שיש לנו לוג גישה, ואנחנו רוצים לספור כמה בקשות לא מוצלחות היו לכל נתיב.

bash
mkdir -p textlab

cat > textlab/access2.log <<'EOF'
2026-10-26 10:00:01 GET /api/users 200
2026-10-26 10:00:02 GET /api/users 500
2026-10-26 10:00:03 POST /api/login 401
2026-10-26 10:00:04 GET /missing 404
2026-10-26 10:00:05 GET /api/users 500
2026-10-26 10:00:06 GET /missing 404
EOF

grep -E ' (4[0-9][0-9]|5[0-9][0-9])$' textlab/access2.log | awk '{ count[$4]++ } END { for (path in count) print path, count[path] }' | sort

grep משאיר רק שורות שמסתיימות בקוד HTTP ממשפחת 4xx או 5xx. אחר כך awk סופר לפי השדה הרביעי, שהוא הנתיב. הפלט הצפוי:

text
/api/login 1
/api/users 2
/missing 2

שימו לב שלא השתמשנו כאן ב־sed, כי לא היה צורך לנקות את הטקסט. צינור טוב הוא לא צינור עם כמה שיותר פקודות, אלא כזה שקל להבין ולתחזק.

Regex שימושי בלי להסתבך

ביטויים רגולריים הם שפה קטנה לחיפוש תבניות. לא צריך לזכור הכול בעל פה, אבל יש כמה סימנים שכדאי להכיר:

סימן משמעות דוגמה
^ תחילת שורה ^ERROR
$ סוף שורה 200$
. כל תו אחד a.c
* אפס או יותר מהתו הקודם ab*
+ אחד או יותר, עם -E [0-9]+
| או, עם -E error|warning
[] קבוצת תווים [A-Z]

המלצה מעשית: ברוב המקרים ב־grep וב־sed, השתמשו ב־-E. זה הופך ביטויים כמו +, ?, | וסוגריים לנוחים יותר לכתיבה.

טעויות נפוצות והודעות שגיאה אמיתיות

grep: invalid option -- P

במערכות מסוימות, בעיקר macOS או סביבות מינימליות, grep -P לא נתמך. הדגל -P מפעיל PCRE, אבל הוא לא זמין בכל מקום.

איך מתקנים: נסו לכתוב את הביטוי עם grep -E במקום. לדוגמה, במקום להישען על תחביר מתקדם, השתמשו ב־[0-9]+ עם -E.

sed: 1: "...": unterminated substitute pattern

הודעה כזו מופיעה לרוב כששכחתם סוגר תוחם בפקודת החלפה, למשל s/foo/bar בלי / אחרון.

איך מתקנים: בדקו שהמבנה הוא תמיד s/מה_מחפשים/במה_מחליפים/flags. אם יש לוכסנים בטקסט עצמו, אפשר להחליף את התוחם לסימן אחר:

bash
printf '%s\n' '/api/users' | sed 's#/api#/v1/api#'

הפלט הצפוי:

text
/v1/api/users

awk: syntax error at source line 1

בדרך כלל זו בעיית גרשיים, סוגריים חסרים, או שימוש בתחביר שלא מתאים לגרסת awk שלכם.

איך מתקנים: התחילו בפקודה קצרה שעובדת, ואז הוסיפו חלקים בהדרגה. לדוגמה:

bash
printf '%s\n' 'a,10' 'b,20' | awk -F, '{ print $1, $2 }'

הפלט הצפוי:

text
a 10
b 20

grep: file.log: No such file or directory

הקובץ לא נמצא בנתיב שסיפקתם. זה קורה הרבה כשמריצים פקודה מתיקייה אחרת.

איך מתקנים: בדקו איפה אתם נמצאים עם pwd, הציגו קבצים עם ls, או השתמשו בנתיב מלא/יחסי נכון.

טיפים לעבודה יומיומית

  • בנו בשלבים: קודם grep, אחר כך הוסיפו awk, ורק בסוף שמרו לקובץ.
  • בדקו לפני דריסה: העדיפו > new-file על פני עריכה במקום עד שאתם בטוחים בתוצאה.
  • צמצמו קלט: אם קובץ גדול, השתמשו ב־head או tail לבדיקה ראשונית.
  • היזהרו עם CSV מורכב: awk -F, טוב לקבצי CSV פשוטים. אם יש שדות עם פסיקים בתוך גרשיים, עדיף להשתמש בכלי ייעודי או בספריית CSV של פייתון.
  • שמרו פקודות שימושיות: פקודה שעזרה לכם פעם אחת כנראה תחזור. אפשר לשמור אותה בקובץ טקסט אישי עם הערה קצרה.

מתי לעבור לסקריפט בפייתון או לכלי אחר

grep, sed ו־awk מצוינים למשימות קצרות, לקבצי טקסט פשוטים ולבדיקות מהירות. אבל אם הלוגיקה גדלה, אם יש טיפול בשגיאות, אם צריך לקרוא JSON עמוק, או אם הקלט מורכב, סקריפט קטן בפייתון יהיה ברור ובטוח יותר. זה לא כישלון של שורת הפקודה; זו בחירה בכלי המתאים.

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

סיכום מעשי

grep, sed ו־awk הם לא קסם עתיק של אנשי לינוקס; הם פשוט כלים קטנים, חדים ומהירים. grep מוצא שורות, sed משנה טקסט, ו־awk עובד עם שדות וחישובים. כשמבינים את החלוקה הזו, הרבה משימות שהיו נראות כמו “צריך לכתוב תוכנה” הופכות לפקודה אחת או שתיים.

הדרך הכי טובה ללמוד היא לקחת קובץ אמיתי ולא מסוכן — לוג מקומי, CSV דוגמה, פלט של פקודת מערכת — ולשאול עליו שאלות קטנות: אילו שורות מעניינות אותי? מה צריך לנקות? לפי איזה שדה אני רוצה לספור? משם, הטרמינל מתחיל להרגיש פחות כמו קיר שחור ויותר כמו סביבת עבודה מדויקת.