Са терминалом: Коришћење регуларних израза ИИ: Замене

У претходном чланку сам на основном нивоу објаснио како функционише сваки од најчешће коришћених специјалних знакова у регуларним изразима. Помоћу ових регуларних израза могуће је вршити сложене претраге у текстуалним датотекама или у излазу других команди. У овом чланку ћу објаснити како се користи команда `sed` за претрагу и замену текста на много моћнији начин него једноставна замена једног текста другим.

Још мало о наредби греп

Пре него што започнем да говорим о сед, желео бих да прокоментаришем нешто више о наредби греп да бих мало довршио оно што је објашњено у претходном чланку. Све што ћу рећи биће релевантно и за ово. Касније ћемо видети везу између овога и претраживања.

Комбиновање регуларних израза

Многи специјални знакови о којима сам говорио у претходном чланку могу се комбиновати, не само са другим знаковима, већ и са целим регуларним изразима. Начин да се то уради је да се помоћу заграда формира подизраз. Погледајмо пример овога. Почнимо са преузимањем текста који можемо користити за тестирање. То је листа фраза. За то ћемо користити следећу команду:

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}', јер би 6 понављао последњи део регуларног израза и оно што желимо је да поновимо све, па оно што морате да ставите је следеће: '([a-zA-Z]+[^a-zA-Z]+){6}'. Са заградама формирамо подизраз и заградама га понављамо 6 пута. Сада само треба да додате „^“ испред и „$“ позади да одговара целој линији. Команда је следећа:

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

А резултат је управо оно што смо желели:

Пева се више од Макарене. Готови сте од Луиса Агуилеа. Имате мање културе од камена. Знате више језика од Цанита Браве. Има више бора од Тутана Кхамона. О бризи о деци знате мање од Рамба.

Приметите да смо ставили параметар -Е јер желимо да користимо проширене регуларне изразе да би „+“ функционисао. Да смо користили основне, морали бисмо да избегнемо заграде и заграде.

Повратне референце или повратне референце

Ако имате инсталирану проверу правописа, вероватно ћете имати списак речи у /usr/share/dict/words. Ако не, можете га инсталирати у арцх са:

sudo pacman -S words

Или у дебиану са:

sudo aptitude install dictionaries-common

Ако желите, можете погледати датотеку да бисте видели које речи садржи. То је заправо веза до датотеке речи за језик на којем је ваш дистро. Можете истовремено инсталирати неколико датотека са речима.

Користићемо ту датотеку. Испоставило се да смо врло радознали да знамо свих седам словних палиндрома тамо. За оне који не знају: палиндром је цапицуа реч, односно може се читати слева надесно, као и здесна налево. Покушајмо са следећом командом:

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

Изгледа помало чудно, зар не? Ако испробамо, резултат ће зависити од језика вашег дистроа и речи које су на вашој листи, али у мом случају са шпанским језиком резултат је следећи:

анилин анилин ваљање

Погледајмо како функционише овај регуларни израз.

Осим „^“ и „$“, за које већ знамо за шта служи, прво што видимо лево су три групе тачака затворене у заградама. Нека вас не збуњују траке испред сваке заграде. Треба да побегну из заграде, јер користимо основне регуларне изразе, али они немају друго значење. Важно је да тражимо било која три знака са тачкама, али свака од тих тачака налази се у заградама. Ово служи за чување знакова који се подударају са тим тачкама како би се на њих поново могло упутити из регуларног израза. Ово је још једна употреба заграда која ће вам касније добро доћи приликом замене.

Овде долазе три броја испод са косом цртом испред себе. У овом случају, шипка је важна. Користи се за означавање да је доњи број позадинска референца и да се односи на једну од претходних заграда. На пример: \ 1 односи се на прву заграду, \ 2 на другу итд.

Другим речима, са регуларним изразом који смо ставили, оно што тражимо су све речи које почињу са било која четири слова, а затим имају слово исто као треће, друго које је исто као друго и друга која је иста као и прва. Резултат су палиндроми од седам слова који се налазе на списку речи. Баш онако како смо и желели.

Да смо користили проширене регуларне изразе, не бисмо морали да избегавамо заграде, али са проширеним регуларним изразима, повратне референце не раде у свим програмима, јер нису стандардизоване. Међутим, са грепом раде, па је то можда још један начин да се то учини. Можете пробати ако желите.

Изрази замене: команда сед

Поред претраживања, једна од најбољих употреба регуларних израза је замена сложених текстова. Да бисте то урадили, један од начина је то помоћу наредбе сед. Моћ команде сед иде далеко даље од замене текста, али овде ћу је искористити за то. Синтакса коју ћу користити са овом наредбом је следећа:

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

Или такође:

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

Где ће РЕГЕКС бити регуларни израз за претрагу, а ЗАМЕНИТИ заменски. Имајте на уму да ова наредба заправо не замењује ништа у датотеци коју назначимо, али оно што показује је да нам показује резултат замене у терминалу, па се немојте плашити наредби које ћу следећи ставити. Нико од њих неће изменити ниједну датотеку на вашем систему.

Почнимо са једноставним примером. Сви имамо разне конфигурационе датотеке у директоријуму / етц које обично имају коментаре који почињу са "#". Претпоставимо да желимо да видимо једну од ових датотека без коментара. На пример, урадићу то са фстаб-ом. Можете покушати са оним кога желите.

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

Нећу овде стављати резултат наредбе, јер то зависи од тога шта имате у вашем фстаб-у, али ако упоредите излаз наредбе са садржајем датотеке, видећете да су сви коментари нестали.

У овој наредби израз за претрагу је «#.*", То је" # "иза којег слиједи било који број знакова, односно коментари. И израз замене, ако погледате две траке заредом, видећете да их нема, па оно што ради је замењивање коментара ничим, односно њихово брисање. Једноставније немогуће.

Сада ћемо учинити супротно. Претпоставимо да оно што желимо је да коментаришемо све редове датотеке. Покушајмо овако:

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

Видећете да у излазу наредбе сви редови почињу са хеш ознаком и празним размаком. Оно што смо урадили је да заменимо почетак реда са «# «. Ово је такође прилично једноставан пример где је текст који треба заменити увек исти, али сада ћемо га мало закомпликовати.

Благодат замена је у томе што у изразу замене можете користити повратне референце попут оних које сам вам раније рекао. Вратимо се датотеци фраза коју смо преузели на почетку чланка. У заграде ћемо ставити сва велика слова која постоје, али то ћемо учинити наредбом:

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

Овде имамо повратну референцу у заменском изразу који се односи на заграде у изразу за претрагу. Заграде у изразу за замену су нормалне заграде. У заменском изразу немају посебно значење, стављају се такви какви јесу. Резултат је да се сва велика слова замењују истим тим словом, било којим, са заградама око њега.

Постоји још један знак који се такође може користити у заменском изразу, то је „&“ и замењује га сав текст који се подудара са изразом за претрагу. Пример за то може бити стављање свих фраза у датотеку под наводнике. То се може постићи овом наредбом:

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

Рад ове наредбе је врло сличан претходној, само што сада замењујемо целу линију са истом линијом са наводницима око ње. Пошто користимо „&“, не треба да стављамо заграде.

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

Ево неколико наредби које сматрам корисним или знатижељним и које користе регуларне изразе. Са овим наредбама корисност регуларних израза је много боља него са примерима које сам вам до сада дао, али чинило се важним објаснити нешто о томе како регуларни изрази раде како би их разумели.

  • Прикажи одељке ман странице:

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

Наравно, команду басх можете променити у било шта што желите. А онда од човека можете директно да одете до одељка који вас занима користећи, наравно, регуларни израз. Притисните «/» да бисте започели претрагу и писање «^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

  • Сазнајте нашу локалну ИП адресу:

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

То се такође може урадити са једном командом сед, али за једноставност је боље да је одвојим на греп и сед.

Неке корисне адресе

Ево неколико адреса које могу бити корисне у вези са регуларним изразима:

  • Библиотека регуларних израза: То је библиотека регуларних израза у којој можете претраживати регуларне изразе повезане са темом која вас занима. Да бисте тражили веб адресе, ИД или било шта друго.
  • РегЕкр: Провера мрежног регуларног израза на мрежи. Омогућава вам да унесете текст и примените регуларни израз на њега или претражите или замените. Даје информације о регуларном изразу и имате неколико могућности да промените његово понашање.
  • Тестер регуларних израза: То је додатак за фирефок који вам омогућава да проверите регуларне изразе из прегледача.

Закључак

За сада је то све. Регуларни изрази су сложени, али корисни. Потребно је време да их научите, али ако сте попут мене, играње с њима ће вам изгледати забавно и мало по мало савладаћете их. То је читав свет. Још увек има пуно тога да се каже о лењим квантификаторима, регуларном изразу у ПЕРЛ стилу, вишередном итд. А онда сваки програм има своје карактеристике и своје варијанте, па је најбољи савет који вам могу дати увек гледати документацију програма коју користите сваки пут када морате да напишете регуларни израз у новом програму.

Хеј! …ХЕЈ! …ПРОБУДИ СЕ! …ШТА СВИ РАДИТЕ ДОК СПАВАТЕ? 

Фуентес

Неке идеје и примере за регуларне изразе у овом чланку преузео сам одавде:


Додај као жељени извор на Гуглу