כיצד להשתמש בפקודה sed בלינוקס

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

כוחו של סד

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

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

באמצעותך sedתוכל לעשות את כל הפעולות הבאות:

  • בחר טקסט
  • טקסט תחליף
  • הוסף שורות לטקסט
  • מחק שורות מהטקסט
  • שנה (או שמור) קובץ מקורי

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

קשורים: כיצד להשתמש בביטויים רגולריים (regexes) בלינוקס

דוגמה פשוטה

ראשית, נשתמש echoלשלוח טקסט כלשהו sedדרך צינור, sed ולהחליף חלק מהטקסט. לשם כך אנו מקלידים את הדברים הבאים:

הד howtogonk | sed's / gonk / geek / '

echoהפקודה שולחת "howtogonk" אל sed, ואת שלטון החלפה פשוטה שלנו ( "ים" מייצג החלפה) מוחל. sed מחפש בטקסט הקלט מופע של המחרוזת הראשונה, ויחליף את כל ההתאמות בשנייה.

המחרוזת "גונק" מוחלפת על ידי "חנון", והמחרוזת החדשה מודפסת בחלון המסוף.

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

בחירת טקסט

אנו נצטרך קובץ טקסט לדוגמאות שלנו. נשתמש בכזה שמכיל מבחר של פסוקים משירו האפי של סמואל טיילור קולרידג '"Rime of the Ancient Mariner".

אנו מקלידים את הדברים הבאים כדי להסתכל על זה באמצעות less:

פחות coleridge.txt

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

כדי לחלץ שורות אחת עד ארבע, אנו מקלידים פקודה זו:

sed -n '1,4p' coleridge.txt

שימו לב לפסיק בין 1לבין 4. pהאמצעים "להדפיס קווים מתאימים." כברירת מחדל,  sed מדפיס את כל השורות. היינו רואים את כל הטקסט בקובץ עם השורות התואמות מודפסות פעמיים. כדי למנוע זאת, נשתמש באפשרות -n(שקטה) כדי לדכא את הטקסט ללא תחרות.

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

sed -n '6,9p' coleridge.txt

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

sed -n -e '1,4p' -e '31, 34p 'coleridge.txt

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

sed -n -e '1,4p' -e '30, 34p 'coleridge.txt

אנו יכולים גם לבחור בשורת התחלה ולהגיד sed לעבור דרך הקובץ ולהדפיס שורות חלופיות, כל שורה חמישית, או לדלג על מספר שורות כלשהו. הפקודה דומה לאלה בה השתמשנו לעיל לבחירת טווח. אולם הפעם נשתמש בטילדה ( ~) במקום בפסיק כדי להפריד בין המספרים.

המספר הראשון מציין את קו ההתחלה. המספר השני מספר sedאילו שורות אחרי קו ההתחלה אנחנו רוצים לראות. המספר 2 פירושו כל שורה שנייה, 3 פירושו כל שורה שלישית וכן הלאה.

אנו מקלידים את הדברים הבאים:

sed -n '1 ~ 2p' coleridge.txt

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

הקרטה ( ^) מייצגת את תחילת הקו. אנו נצרף את מונח החיפוש שלנו בקו נטוי קדימה ( /). אנו כוללים גם רווח אחרי "And" כך שמילים כמו "Android" לא ייכללו בתוצאה.

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

sed -n '/ ^ And / p' coleridge.txt

שלוש שורות שמתחילות ב- "And" מופקות מהקובץ ומוצגות עבורנו.

ביצוע החלפות

בדוגמה הראשונה הראינו לך את הפורמט הבסיסי הבא sedלהחלפה:

הד howtogonk | sed's / gonk / geek / '

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

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

sed -n 's / day / week / p' coleridge.txt

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

sed -n 's / day / week / gp' coleridge.txt

זה תואם שלושה מתוך הארבעה בשורה הראשונה. מכיוון שהמילה הראשונה היא "יום", והיא sedתלויה באותיות רישיות, היא אינה רואה במופע זהה ל"יום ".

אנו מקלידים את הדברים הבאים ומוסיפים i את הפקודה בסוף הביטוי כדי לציין רגישות לאותיות רישיות:

sed -n 's / day / week / gip' coleridge.txt

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

לדוגמה, אם אנו סוגרים תווים בסוגריים מרובעים ( []), הם מתפרשים כ"כל תו מרשימת התווים הזו ".

אנו מקלידים את הדברים הבאים, וכוללים את "D" ו- ​​"d" בקבוצה, כדי להבטיח שהוא תואם את "יום" ו"יום ":

sed -n 's / [Dd] ay / week / gp' coleridge.txt

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

sed -n '1,4p' coleridge.txt

נחפש שני רווחים ונחליף אותם באחד. אנו נעשה זאת באופן גלובלי כך שהפעולה תחזור על עצמה לאורך כל הקו. כדי להיות ברור, דפוס החיפוש הוא רווח, כוכב רווח ( *), ומחרוזת ההחלפה היא רווח יחיד. 1,4מגביל ההחלפה לארבע השורות הראשונות של הקובץ.

שמנו את כל זה יחד בפקודה הבאה:

sed -n '1,4 s / * / / gp' coleridge.txt

זה עובד יפה! דפוס החיפוש הוא מה שחשוב כאן. הכוכבית ( *) מייצגת אפס או יותר מהתו הקודם, שהוא רווח. לפיכך, דפוס החיפוש מחפש מחרוזות של חלל אחד או יותר.

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

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

sed -n '1,4 s / * / / gp' coleridge.txt

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

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

אנו מקלידים את הדברים הבאים תוך שימוש ב -e(ביטוי) בו השתמשנו קודם לכן, המאפשר לנו לבצע שתי החלפות או יותר בו זמנית:

sed -n -e 's / motion / flutter / gip' -e 's / ocean / gutter / gip' coleridge.txt

אנו יכולים להשיג אותה תוצאה אם ​​נשתמש בנקודה-פסיק ( ;) כדי להפריד בין שני הביטויים, כך:

sed -n 's / motion / flutter / gip; s / ocean / gutter / gip' coleridge.txt

כאשר החלפנו "יום" ל"שבוע "בפקודה הבאה, גם המופע של" יום "בביטוי" טוב יום "הוחלף:

sed -n 's / [Dd] ay / week / gp' coleridge.txt

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

אנו מקלידים את הדברים הבאים כדי להפוך את דפוס ההתאמה שלנו למילה "אחרי":

sed -n '/ after / s / [Dd] ay / week / gp' coleridge.txt

זה נותן לנו את המענה שאנחנו רוצים.

תחליפים מורכבים יותר

בואו נתן הפסקה לקולרידג 'ונשתמש sedבכדי לחלץ שמות etc/passwdמהקובץ.

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

עליך לסגור את ביטוי המשנה בסוגריים [ ()] כדי שזה יעבוד. לפני הסוגריים צריך להקדים קו נטוי לאחור ( \) כדי למנוע התייחסות אליהם כאל אופי רגיל.

לשם כך, הקלד את הדברים הבאים:

sed 's / \ ([^:] * \). * / \ 1 /' / etc / passwd

בואו נשבור את זה:

  • sed 's/:sed פקוד ותחילת ביטוי ההחלפה.
  • \(: סוגר הפתיחה [ (] הסוגר את ביטוי המשנה, לפניו קו נטוי אחורי ( \).
  • [^:]*: ביטוי המשנה הראשון של מונח החיפוש מכיל קבוצה בסוגריים מרובעים. המשמעות של הקרטה ( ^) היא "לא" כאשר משתמשים בה בקבוצה. קבוצה פירושה שכל תו שאינו נקודתיים ( :) יתקבל כמשחק.
  • \): סוגר הסגירה [ )] עם קו נטוי אחורי ( \).
  • .*: ביטוי משנה זה בחיפוש השני פירושו "כל תו ומספר כלשהו שלהם."
  • /\1: חלק ההחלפה של הביטוי מכיל 1קדימה אחורית ( \). זה מייצג את הטקסט התואם לביטוי המשנה הראשון.
  • /': הסגירה הקדמית הסגירה ( /) והציטוט היחיד ( ') מסיימות את sedהפקודה.

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

כל שורה /etc/passwdבקובץ מתחילה בשם משתמש עם סיום נקודתיים. אנו מתאימים הכל עד למעי הגס הראשון, ואז מחליפים ערך זה עבור כל השורה. אז בידדנו את שמות המשתמש.

לאחר מכן נצרף את ביטוי המשנה השני בסוגריים [ ()] כדי שנוכל להפנות אותו גם למספר. נחליף גם \1 ב- \2. הפקודה שלנו תחליף כעת את כל השורה בכל מהמעי הגס הראשונה ( :) ועד סוף השורה.

אנו מקלידים את הדברים הבאים:

sed 's / \ ([^:] * \) \ (. * \) / \ 2 /' / etc / passwd

השינויים הקטנים האלה הופכים את משמעות הפקודה, ואנחנו מקבלים הכל חוץ משמות המשתמש.

עכשיו, בואו נסתכל על הדרך המהירה והקלה לעשות זאת.

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

אז אנו מקלידים את הדברים הבאים, קוצצים הכל מהמעי הגס ( :) עד סוף השורה ומשאירים רק את שמות המשתמש:

sed's /:.*// "/ etc / passwd

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

יש לנו קובץ פסיקים ( ,) המפריד בין שמות פרטיים ושמות משפחה. אנו רוצים לרשום אותם כ"שם משפחה, שם פרטי ". אנו יכולים להשתמש  cat, כפי שמוצג למטה, כדי לראות מה יש בקובץ:

geeks.txt חתול

כמו הרבה sedפקודות, זו הבאה עשויה להיראות בלתי חדירה בהתחלה:

sed 's / ^ \ (. * \), \ (. * \) $ / \ 2, \ 1 / g' geeks.txt

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

  • sed 's/: פקודת ההחלפה הרגילה.
  • ^: מכיוון שהמטפל אינו בקבוצה ( []), פירושו "התחלת הקו."
  • \(.*\),: ביטוי המשנה הראשון הוא כל מספר של כל תו. הוא מוקף בסוגריים [ ()], שלכל אחד מהם מקדים קו נטוי אחורי ( \) כך שנוכל להתייחס אליו לפי מספר. כל דפוס החיפוש שלנו מתורגם עד כה כחיפוש מתחילת השורה ועד הפסיק הראשון ( ,) למספר כלשהו של תווים.
  • \(.*\):  ביטוי המשנה הבא הוא (שוב) כל מספר של כל תו. הוא גם מוקף בסוגריים [ ()], לפני שניהם קו נטוי אחורי ( \) כך שנוכל להפנות את הטקסט התואם לפי מספר.
  • $/: סימן הדולר ( $) מייצג את סוף השורה ויאפשר לחיפוש שלנו להמשיך עד סוף השורה. השתמשנו בזה פשוט כדי להציג את סימן הדולר. אנחנו לא באמת צריכים את זה כאן, מכיוון שהכוכבית ( *) תגיע לסוף השורה בתרחיש זה. קו נטוי קדימה ( /) משלים את החלק של דפוס החיפוש.
  • \2,\1 /g': מכיוון שסגרנו את שני תת-הביטויים שלנו בסוגריים, אנו יכולים להתייחס לשניהם לפי מספרם. מכיוון שאנחנו רוצים להפוך את הסדר, אנו מקלידים אותם כ- second-match,first-match. יש להקדים את המספרים על ידי קו נטוי אחורי ( \).
  • /g: זה מאפשר לפקודה שלנו לעבוד באופן גלובלי על כל שורה.
  • geeks.txt: הקובץ עליו אנו עובדים.

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

sed '/ צוואר / c סביב פרק ​​כף היד שלי היה מתוח' coleridge.txt

השורה החדשה שלנו מופיעה כעת בתחתית התמצית שלנו.

הכנסת שורות וטקסט

אנחנו יכולים גם להוסיף שורות חדשות וטקסט לקובץ שלנו. כדי להוסיף שורות חדשות לאחר שורות תואמות, נשתמש בפקודה הוסף ( a).

הנה הקובץ שאיתו נעבוד:

geeks.txt חתול

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

אנו מקלידים את הדברים הבאים כדי לחפש שורות המכילות את המילה "הוא", ומכניסים שורה חדשה תחתיהן:

sed '/ He / a -> הוכנס!' geeks.txt

אנו מקלידים את הדברים הבאים וכוללים את הפקודה Insert ( i) כדי להוסיף את השורה החדשה מעל אלה המכילים טקסט תואם:

sed '/ He / i -> הוכנס!' geeks.txt

אנו יכולים להשתמש בסמל-החולף ( &), המייצג את הטקסט המותאם המקורי, כדי להוסיף טקסט חדש לשורה תואמת. \1 ,  \2וכן הלאה, מייצגים ביטויי משנה תואמים.

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

כדי לעשות זאת, אנו מקלידים את הדברים הבאים:

sed 's /.*/--> הוכנס & /' geeks.txt

אנו מקלידים את הדברים הבאים, כולל Gהפקודה, שתוסיף שורה ריקה בין כל שורה:

סיד 'G' geeks.txt

אם אתה רוצה להוסיף שתיים או יותר שורות ריקות, אתה יכול להשתמש G;GG;G;Gוכן הלאה.

מחיקת קווים

הפקודה מחק ( d) מוחקת שורות התואמות לדפוס חיפוש, או את אלה שצוינו עם מספרי שורות או טווחים.

לדוגמה, כדי למחוק את השורה השלישית, נקליד את הדברים הבאים:

שקט '3d' geeks.txt

כדי למחוק את טווח השורות ארבע עד חמש, נקליד את הדברים הבאים:

שקט '4,5d' geeks.txt

כדי למחוק שורות מחוץ לטווח, אנו משתמשים בסימן קריאה ( !), כמוצג להלן:

sed '6,7! d' geeks.txt

שומר את השינויים שלך

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

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

לקבלת שקט נפשי, sed ניתן ליצור גיבוי של הקובץ המקורי לפני שהוא מבצע את הפקודה שלו.

אתה יכול להשתמש באפשרות במקום ( -i) כדי לומר  sedלכתוב את השינויים בקובץ המקורי, אך אם תוסיף לו סיומת קובץ, sed יגבה את הקובץ המקורי לקובץ חדש. יהיה לו שם זהה לקובץ המקורי, אך עם סיומת קובץ חדשה.

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

כדי לעשות זאת, אנו מקלידים את הדברים הבאים:

sed -i'.bak '' /^.*He.*$/d 'geeks.txt

אנו מקלידים את הדברים הבאים כדי לוודא שקובץ הגיבוי שלנו לא משתנה:

geeks.txt.bak חתול

אנו יכולים גם להקליד את הדברים הבאים כדי להפנות את הפלט לקובץ חדש ולהשיג תוצאה דומה:

sed -i'.bak '' /^.*He.*$/d 'geeks.txt> new_geeks.txt

אנו catנוהגים לאשר שהשינויים נכתבו בקובץ החדש, כמוצג להלן:

חתול new_geeks.txt

אחרי ששכבתי את כל זה

כפי שבוודאי שמתם לב, אפילו הפריימר המהיר הזה sedארוך למדי. יש הרבה לפקודה הזו, ואפשר לעשות עוד יותר איתה.

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