עם מסוף: שימוש בביטויים רגולריים II: החלפות

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

קצת יותר על הפקודה grep

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

שילוב ביטויים רגולריים

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

curl http://artigoo.com/lista-de-frases-comparativas-comicas 2>/dev/null | sed -n 's/.*\(.*\.\)<\/p>/\1/gp' > frases

 זה ישאיר אותך בספרייה בה אתה מפעיל קובץ בשם «ביטויים». אתה יכול לפתוח את זה כדי להעיף מבט ולצחוק קצת. 🙂

בואו נניח שנרצה למצוא את הביטויים המכילים 6 מילים בדיוק. הקושי הוא ליצור ביטוי קבוע התואם לכל מילה. מילה היא רצף של אותיות, באותיות רישיות או באותיות קטנות, וזה יהיה בערך כמו '[a-zA-Z]+', אבל אתה גם צריך לציין כי האותיות האלה צריכות להיות מופרדות על ידי תווים אחרים מאשר אותיות, כלומר, זה יהיה משהו כמו '[a-zA-Z]+[^a-zA-Z]+'. זכרו: "^" כתו הראשון בסוגריים מציין שאנחנו רוצים להתאים לתווים שאינם בטווחים וה- "+" מציין תו אחד או יותר.

יש לנו כבר ביטוי קבוע שיכול להתאים למילה. כדי לזווג אותה עם 6, יהיה צורך לחזור עליה 6 פעמים. לשם כך השתמשנו במקשים, אך אין טעם לשים אותם '[a-zA-Z]+[^a-zA-Z]+{6}'מכיוון שה 6 יחזרו על החלק האחרון של הביטוי הרגולרי ומה שאנחנו רוצים זה לחזור על הכל, אז מה שיש לנו לשים זה: '([a-zA-Z]+[^a-zA-Z]+){6}'. בסוגריים אנו יוצרים תת-ביטוי ועם הפלטה אנו חוזרים עליו 6 פעמים. עכשיו אתה רק צריך להוסיף "^" מלפנים ו- "$" מאחור כדי להתאים את כל השורה. הפקודה היא כדלקמן:

grep -E '^([a-zA-Z]+[^a-zA-Z]+){6}$' frases

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

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

שימו לב שאנחנו שמים את הפרמטר -E מכיוון שאנחנו רוצים להשתמש בביטויים רגולריים מורחבים כדי לגרום ל" + "לעבוד. אם היינו משתמשים בסיסיים, היינו צריכים לברוח מהסוגריים ומהסוגרים.

הפניות אחוריות או הפניות אחוריות

אם מותקן אצלך בודק איות, ככל הנראה תהיה לך רשימת מילים /usr/share/dict/words. אם לא, אתה יכול להתקין אותו בקשת עם:

sudo pacman -S words

או בדיביין עם:

sudo aptitude install dictionaries-common

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

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

grep '^\(.\)\(.\)\(.\).\3\2\1$' /usr/share/dict/words

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

אנילין אנילין מתגלגל

בואו נראה איך הביטוי הקבוע הזה עובד.

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

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

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

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

ביטויי החלפה: הפקודה sed

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

sed [-r] 's/REGEX/REPL/g' FICHERO

או גם:

COMANDO | sed [-r] 's/REGEX/REPL/g'

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

נתחיל בדוגמא פשוטה. לכולנו קבצי תצורה שונים בספריית / etc, שלרוב יש להם הערות המתחילות ב- "#". נניח שאנחנו רוצים לראות את אחד הקבצים האלה ללא ההערות. לדוגמה, אני הולך לעשות את זה עם ה- fstab. אתה יכול לנסות עם זה שאתה רוצה.

sed 's/#.*//g' /etc/fstab

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

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

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

sed 's/^/# /g' /etc/fstab

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

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

sed 's/\([A-Z]\)/(\1)/g' frases

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

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

sed 's/.*/"&"/g' frases

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

כמה פקודות שימושיות עם ביטויים רגולריים

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

  • הצג קטעים מדף גבר:

man bash | grep '^[A-Z][A-Z ]*$'

כמובן, אתה יכול לשנות את הפקודה bash לכל מה שתרצה. ואז מאדם, אתה יכול ללכת ישירות לקטע שמעניין אותך להשתמש, כמובן, בביטוי קבוע. אתה לוחץ על «/» כדי להתחיל לחפש ולכתוב «^ALIASES$»כדי לעבור לסעיף ALIASES, למשל. אני חושב שזה השימוש הראשון שהתחלתי לעשות בביטויים קבועים לפני כמה שנים. מעבר לדפים מסוימים במדריך הוא כמעט בלתי אפשרי בלי טריק כזה.

  • הראה את שמות כל משתמשי המכונה כולל שמות מיוחדים:

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

  • הצג שמות משתמשים, אך רק אלה עם מעטפת:

grep -vE '(/false|/nologin)$' /etc/passwd | sed 's/\([^:]*\).*/\1/g'

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

  • הכנס פסיק לפני שלוש הספרות האחרונות של כל המספרים בקובץ המספרים:

sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers

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

  •  חלץ את כל כתובות הדוא"ל מקובץ:

grep -E '\<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\>' FICHERO

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

sed -r 's/([0-9]{2})[/-]([0-9]{2})[/-]([0-9]{4})/Día: \1, Mes: \2, Año: \3/g' FICHERO

  • גלה את ה- IP המקומי שלנו:

/sbin/ifconfig | grep 'inet .*broadcast' | sed -r 's/[^0-9]*(([0-9]+\.){3}[0-9]+).*/\1/g'

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

כמה כתובות שימושיות

להלן מספר כתובות שעשויות להיות שימושיות הקשורות לביטויים רגולריים:

  • ספריית הבעה רגילה: זוהי ספריית ביטויים רגילים בה תוכלו לחפש ביטויים רגולריים הקשורים לנושא שמעניין אתכם. לחיפוש כתובות אינטרנט, תעודת זהות או כל דבר אחר.
  • RegExr: בודק ביטוי רגיל מקוון. זה מאפשר לך להזין טקסט ולהחיל עליו ביטוי רגולרי או לחפש או להחליף. זה נותן מידע על הביטוי הרגולרי ויש לך כמה אפשרויות לשנות את התנהגותו.
  • בודק ביטויים רגילים: זהו תוסף ל- Firefox המאפשר לבדוק ביטויים רגולרים מהדפדפן.

מסקנה

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

היי! …היי! … תתעורר! ... מה כולכם עושים שינה? 🙂

פואנטס

כמה מהרעיונות והדוגמאות לביטויים קבועים במאמר זה לקחתי מכאן:


15 תגובות, השאר את שלך

השאירו את התגובה שלכם

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

*

*

  1. אחראי לנתונים: מיגל אנחל גטון
  2. מטרת הנתונים: בקרת ספאם, ניהול תגובות.
  3. לגיטימציה: הסכמתך
  4. מסירת הנתונים: הנתונים לא יועברו לצדדים שלישיים אלא בהתחייבות חוקית.
  5. אחסון נתונים: מסד נתונים המתארח על ידי Occentus Networks (EU)
  6. זכויות: בכל עת תוכל להגביל, לשחזר ולמחוק את המידע שלך.

  1.   אלב דיג'ו

    אוּמָנוּתִי!!!

    1.    הקסבורג דיג'ו

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

      1.    אוסקר דיג'ו

        אני אוהב את זה חה!

        1.    הקסבורג דיג'ו

          ואז בטח עשיתי משהו נכון. לצחוק בקול רם!! 🙂

          תודה רבה על תגובתך.

          1.    בלייר פסקל דיג'ו

            לעזאזל תמשיך לכתוב גבר, תמשיך כך.

          2.    הקסבורג דיג'ו

            @Blaire Pascal: תגובות כמו שלך מעודדות את זה. 🙂 תודה רבה !!

      2.    סיטוקס דיג'ו

        אהבתי את זה גם ... תודה 🙂

        1.    הקסבורג דיג'ו

          תודה על התגובה. אני מקווה לכתוב עוד כמה. 🙂

  2.   מריאן דיג'ו

    ההודעות שלך פנטסטיות, אתה לומד הרבה, אלא לומד לבצע משימות בצורה אלגנטית ויעילה.

    חשבת לאסוף את כל הודעות סקריפט המעטפת שלך? מיון לקובץ PDF היה מדריך נהדר.

    הידד ותודה רבה!

    1.    הקסבורג דיג'ו

      תודה רבה!! זה לא רעיון רע. כרגע יש רק שניים, אבל אחשוב על כך בהמשך. 🙂

  3.   קיוב דיג'ו

    מאמר טוב מאוד, 5+.

    1.    הקסבורג דיג'ו

      תודה. אני שמח שאתה אוהב את זה. 🙂

  4.   סבסטיאן דיג'ו

    מְעוּלֶה! אני צריך לשנות את הביטוי הבא ואני לא יודע איך לעשות את זה:
    192.168.0.138/ שרת מאת 192.168.0.111/data
    הבעיה נעוצה בסמל "/".
    אני משתמש בפקודה:
    למצוא. -name "* .txt" -exec sed -i 's / TEXT1 / TEXT2 / g' {} \;
    מה משמש לביצוע משימות מסוג זה באופן מחלחל, אבל אני לא יכול ...
    האם מישהו יודע כיצד עלי לעשות זאת?
    לְחַבֵּק!
    סבע

    1.    הקסבורג דיג'ו

      מה שאתה צריך לעשות זה לברוח מהדמות ככה:

      למצוא. -name "* .txt" -exec sed -i 's / \ / Server / \ / data / g' {} \;

      אתה יכול גם להשתמש במפריד אחר בסד. זה לא חייב להיות בר. Sed מאפשר להשתמש בכל דמות. לדוגמה, זה יהיה ברור יותר:

      למצוא. -name "* .txt" -exec sed -i 's | / Server | / data | g' {} \;

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

      ברכות.

  5.   סבסטיאן דיג'ו

    מְעוּלֶה!!!!
    חיפשתי פיתרון זה זמן רב.
    כאן אני משאיר את הפקודה המלאה בה השתמשתי

    למצוא. -name "* .txt" -exec sed -i 's | 192 \ .168 \ .0 \ .238 \ / Server | 192 \ .168 \ .0 \ .111 \ / data | g' {} \;

    היתרון של פקודה זו הוא שהיא משנה את כל קבצי ה- .txt (או את הסיומת הרצויה) רקורסיבית ... עליכם להיות זהירים מאוד!
    אבל זה מאוד שימושי !!!

    ובכן, תודה על הכל ואלף מזל טוב לכל הקבוצה.
    תמיד קראתי אותם מהדואר!
    חיבוקים
    סבע