С терминал: Използване на регулярни изрази 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]+'. Не забравяйте: „^“ като първият знак в скобите показва, че искаме да съвпаднем с символи, които не са в диапазоните, а „+“ показва 1 или повече знака.

Вече имаме регулярен израз, който може да съответства на дума. За да го сдвоите с 6, ще трябва да се повтори 6 пъти. За това използвахме клавишите, но е безполезно да се поставя '[a-zA-Z]+[^a-zA-Z]+{6}', защото шестицата би повторила последната част от регулярния израз и това, което искаме, е да повторим всичко, така че това, което трябва да поставите, е следното: '([a-zA-Z]+[^a-zA-Z]+){6}'. Със скобите оформяме субекспресия и със скобите го повтаряме 6 пъти. Сега просто трябва да добавите „^“ отпред и „$“ отзад, за да съответства на целия ред. Командата е както следва:

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

И резултатът е точно това, което искахме:

Пее се повече от Макарена. Вие сте по-завършени от Луис Агиле. Имате по-малко култура от камък. Знаете повече езици от Cañita Brava. Той има повече бръчки от Тутан Хамон. Знаете по-малко от Рамбо за грижите за децата.

Забележете, че поставяме параметъра -E, защото искаме да използваме разширени регулярни изрази, за да накараме "+" да работи. Ако използвахме основните, ще трябва да избягаме от скобите и скобите.

Обратни препратки или препратки

Ако имате инсталирана програма за проверка на правописа, вероятно ще имате списък с думи в /usr/share/dict/words. Ако не, можете да го инсталирате в arch с:

sudo pacman -S words

Или в debian с:

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

Ще видите, че в изхода на командата всички редове започват с хеш знак и празно място. Това, което направихме, е да заменим началото на реда с «# «. Това също е доста прост пример, при който текстът, който трябва да бъде заменен, винаги е един и същ, но сега ще го усложним още малко.

Благодатта на заместванията е, че в израза за заместване можете да използвате обратни препратки като тези, които ви казах преди. Да се ​​върнем към файла с фрази, който изтеглихме в началото на статията. Ще поставим в скоби всички главни букви, които има, но ще го направим с команда:

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

Това, което имаме тук, е обратна препратка в заместващия израз, който се отнася до скобите в израза за търсене. Скобите в заместващия израз са нормални скоби. В заместващия израз те нямат специално значение, те се поставят такива, каквито са. Резултатът е, че всички главни букви се заменят със същата буква, каквато и да е, със скоби около нея.

Има и друг знак, който също може да се използва в заместващия израз, той е "&" и той се заменя с целия текст, съответстващ на израза за търсене. Пример за това може да бъде поставянето на всички фрази във файла в кавички. Това може да се постигне с тази команда:

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

Действието на тази команда е много подобно на предишната, само че сега това, което заместваме, е целият ред със същия ред с кавички около него. Тъй като използваме „&“, не е нужно да поставяме скоби.

Някои полезни команди с регулярни изрази

Ето няколко команди, които намирам за полезни или любопитни и които използват регулярни изрази. С тези команди полезността на регулярните изрази е много по-добра, отколкото с примерите, които ви дадох досега, но ми се струва важно да обясня нещо за това как работят регулярните изрази, за да ги разбера.

  • Показване на раздели на човешка страница:

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

Разбира се, можете да промените командата bash на каквото искате. И след това от човек, можете да отидете директно в раздела, който ви интересува, използвайки, разбира се, регулярен израз. Натиснете «/», за да започнете да търсите и пишете «^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 за простота.

Някои полезни адреси

Ето някои адреси, които могат да бъдат полезни, свързани с регулярни изрази:

  • Библиотека с регулярни изрази: Това е библиотека на регулярни изрази, където можете да търсите регулярни изрази, свързани с темата, която ви интересува. За да търсите уеб адреси, ID или каквото и да било.
  • RegExr: Онлайн проверка на регулярни изрази. Тя ви позволява да въведете текст и да приложите регулярен израз към него или да търсите, или да замените. Той дава информация за регулярния израз и имате няколко опции за промяна на поведението му.
  • Тестер за регулярни изрази: Това е добавка за firefox, която позволява проверка на регулярни изрази от браузъра.

Заключение

Засега това е всичко. Регулярните изрази са сложни, но полезни. Отнема време, за да ги научите, но ако сте като мен, играта с тях ще изглежда забавно и малко по малко ще ги овладеете. Това е цял свят. Все още ще има какво да се каже за мързеливи квантори, регекс в стил PERL, многоредов и т.н. И тогава всяка програма има своите характеристики и своите варианти, така че най-добрият съвет, който мога да ви дам, е винаги да разглеждате документацията на програмата, която използвате всеки път, когато трябва да напишете регулярен израз в нова програма.

Хей! …ХЕЙ! … СЪБУДЕТЕ СЕ! ... КАКВО ВСИЧКИ ПРИЕМАТЕ? 🙂

Фуентес

Някои от идеите и примерите за регулярни изрази в тази статия съм взел от тук:


Оставете вашия коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *

*

*

  1. Отговорен за данните: Мигел Анхел Гатон
  2. Предназначение на данните: Контрол на СПАМ, управление на коментари.
  3. Легитимация: Вашето съгласие
  4. Съобщаване на данните: Данните няма да бъдат съобщени на трети страни, освен по законово задължение.
  5. Съхранение на данни: База данни, хоствана от Occentus Networks (ЕС)
  6. Права: По всяко време можете да ограничите, възстановите и изтриете информацията си.

  1.   елав каза той

    Майсторски !!!

    1.    хексборг каза той

      Не е толкова лошо, но много благодаря. Надявам се, че хората харесват. 🙂

      1.    "Оскар" каза той

        Харесва ми ха!

        1.    хексборг каза той

          Тогава трябва да съм направил нещо както трябва. LOL !! 🙂

          Благодаря ви много за вашия коментар.

          1.    Блер паскал каза той

            По дяволите, продължавай да пишеш, продължавай.

          2.    хексборг каза той

            @Blaire Pascal: Коментари като вашия го насърчават. 🙂 Благодаря ви много !!

      2.    град каза той

        На мен също ми хареса ... благодаря 🙂

        1.    хексборг каза той

          Благодаря ви за коментар. Надявам се да напиша още няколко. 🙂

  2.   Мариан каза той

    Вашите публикации са фантастични, научавате много, по-скоро се научавате да изпълнявате задачи по елегантен и ефективен начин.

    Мислили ли сте за събиране на всичките си публикации за скриптове на черупки? Сортирано в pdf ще стане чудесно ръководство.

    Наздраве и много благодаря!

    1.    хексборг каза той

      Благодаря много!! Това не е лоша идея. В момента са само две, но ще помисля по-късно. 🙂

  3.   Кийов каза той

    много добра статия, 5+.

    1.    хексборг каза той

      Благодаря ти. Радвам се че ти харесва. 🙂

  4.   Себастиан каза той

    Отлично! Трябва да променя следния израз и не знам как да го направя:
    192.168.0.138/ Сървър от 192.168.0.111/data
    Проблемът се крие в символа "/".
    Използвам командата:
    намирам. -име "* .txt" -exec sed -i 's / TEXT1 / TEXT2 / g' {} \;
    Какво се използва, за да се изпълни този тип умишлено, но не мога ...
    Някой знае ли как трябва да го направя?
    Прегръдка!
    Seba

    1.    хексборг каза той

      Това, което трябва да направите, е да избягате от героя по този начин:

      намирам. -име "* .txt" -exec sed -i 's / \ / Server / \ / data / g' {} \;

      Можете също да използвате друг сепаратор в sed. Не е задължително да е бар. Sed позволява да се използва всеки символ. Например, това би било по-ясно:

      намирам. -име "* .txt" -exec sed -i '| | / Сървър | / данни | g' {} \;

      И ако ще копирате и поставите командите от този коментар, бъдете внимателни с кавичките, че wordpress ги променя за типографските. 🙂

      Поздрави.

  5.   Себастиан каза той

    Отлично !!!!
    Отдавна търся това решение.
    Тук оставям пълната команда, която съм използвал

    намирам. -име "* .txt" -exec sed -i 's | 192 \ .168 \ .0 \ .238 \ / Сървър | 192 \ .168 \ .0 \ .111 \ / data | g' {} \;

    Предимството на тази команда е, че тя променя рекурсивно всички .txt файлове (или разширението, което искате) ... Трябва да бъдете много внимателни!
    Но е много полезно !!!

    Е, благодаря за всичко и хиляда поздравления за цялата група.
    Винаги ги чета от пощата!
    Прегръдки
    Seba