S terminalom: Uporaba regularnih izrazov II: Zamenjave

V sebi prejšnji članek Na osnovni ravni sem vam povedal, kako deluje vsak izmed najbolj uporabljenih posebnih znakov regularnih izrazov. S temi regularnimi izrazi je mogoče zapleteno iskati v besedilnih datotekah ali na izhodu drugih ukazov. V tem članku bom razložil, kako uporabiti sed ukaz za iskanje in zamenjavo besedila na veliko močnejši način kot preprosto spreminjanje enega besedila za drugega.

Še nekaj o ukazu grep

Preden začnem govoriti o sed, bi rad še malo pokomentiral ukaz grep, da nekoliko dopolnim to, kar je bilo pojasnjeno v prejšnjem članku. Vse, kar bom rekel, bo pomembno tudi za to. Kasneje bomo videli razmerje med tem in iskanji.

Kombiniranje regularnih izrazov

Številne posebne znake, o katerih sem že govoril v prejšnjem članku, je mogoče kombinirati, ne samo z drugimi znaki, temveč s celimi regularnimi izrazi. Način za to je, da z oklepaji oblikujemo podizraz. Poglejmo primer tega. Začnimo s prenosom besedila, ki ga lahko uporabimo za testiranje. To je seznam besednih zvez. Za to bomo uporabili naslednji ukaz:

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

 Tako boste ostali v imeniku, v katerem zaženete datoteko z imenom »fraze«. Lahko ga odprete, da si ogledate in se malo nasmejete. 🙂

Zdaj pa predpostavimo, da želimo najti besedne zveze, ki imajo natanko 6 besed. Težava je v oblikovanju regularnega izraza, ki se ujema z vsako besedo. Beseda je zaporedje črk, bodisi velike ali male, kar bi bilo nekaj takega '[a-zA-Z]+', vendar morate tudi navesti, da morajo biti te črke ločene z drugimi znaki, razen črk, to pomeni, da bi bilo nekaj takega '[a-zA-Z]+[^a-zA-Z]+'. Ne pozabite: "^" kot prvi znak v oklepajih pomeni, da se želimo ujemati z znaki, ki niso v obsegu, "+" pa pomeni 1 ali več znakov.

Že imamo regularni izraz, ki se lahko ujema z besedo. Če ga želite združiti s 6, ga boste morali ponoviti 6-krat. Za to smo uporabili tipke, vendar je neuporabno postavljati '[a-zA-Z]+[^a-zA-Z]+{6}', ker bi šestica ponovila zadnji del regularnega izraza in kar želimo, je, da ponovimo vse, zato morate dodati naslednje: '([a-zA-Z]+[^a-zA-Z]+){6}'. Z oklepaji oblikujemo podizraz in z oklepaji ponovimo 6-krat. Zdaj morate samo dodati "^" spredaj in "$" zadaj, da se ujema s celo vrstico. Ukaz je naslednji:

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

In rezultat je ravno tisto, kar smo želeli:

Poje se bolj kot Macarena. Končali ste bolj kot Luis Aguilé. Imate manj kulture kot kamen. Znate več jezikov kot Cañita Brava. Ima več gub kot Tutan Khamón. O varstvu otrok veste manj kot Rambo.

Upoštevajte, da smo parameter -E postavili, ker želimo uporabiti razširjene regularne izraze, da bo "+" deloval. Če bi uporabili osnovne, bi morali ubežati oklepaju in oklepaju.

Povratne reference ali povratne reference

Če imate nameščen črkovalnik, boste verjetno imeli seznam besed v /usr/share/dict/words. Če ne, ga lahko namestite v arch z:

sudo pacman -S words

Ali v debianu z:

sudo aptitude install dictionaries-common

Če želite, si lahko ogledate datoteko, da vidite, katere besede ima. To je pravzaprav povezava do besedne datoteke za jezik, v katerem je vaš distro. Lahko imate nameščenih več besednih datotek hkrati.

Uporabili bomo to datoteko. Izkazalo se je, da smo zelo radovedni, da poznamo vseh sedem črkovnih palindromov tam zunaj. Za tiste, ki ne vedo: palindrom je beseda capicúa, torej jo je mogoče brati od leve proti desni kot tudi od desne proti levi. Poskusimo z naslednjim ukazom:

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

Izgleda nekoliko čudno, kajne? Če poskusimo, bo rezultat odvisen od jezika vaše distribucije in besed na vašem seznamu, v mojem primeru pa pri španskem jeziku je rezultat tak:

valjanje anilina

Poglejmo, kako deluje ta regularni izraz.

Poleg "^" in "$", za katero že vemo, za kaj služi, najprej na levi vidimo tri skupine pik, ki so v oklepajih. Naj vas ne zmedejo palice pred vsako oklepajem. Umaknili se bodo oklepaju, ker uporabljamo osnovne regularne izraze, nimajo pa drugega pomena. Pomembno je, da zahtevamo poljubne tri znake s pikami, vendar je vsaka od teh pik zaprta v oklepajih. S tem shranite znake, ki se ujemajo s temi točkami, tako da jih je mogoče znova sklicevati iz regularnega izraza. To je še ena uporaba oklepajev, ki vam bo kasneje prišla prav pri nadomeščanju.

Tu prihajajo tri spodnje številke s poševnico pred njimi. V tem primeru je vrstica pomembna. Uporablja se za označevanje, da je spodnja številka referenčna referenca in se nanaša na enega od prejšnjih oklepajev. Na primer: \ 1 se nanaša na prvo oklepaj, \ 2 na drugo itd.

To pomeni, da z regularnim izrazom, ki smo ga postavili, iščemo vse besede, ki se začnejo s poljubnimi štirimi črkami in imajo potem črko, ki je enaka tretji, druga, ki je enaka drugi in druga to je enako kot prvo. Rezultat je sedem črkovnih palindromov, ki so na seznamu besed. Tako kot smo želeli.

Če bi uporabljali razširjene regularne izraze, oklepajev ne bi bilo treba ubežati, pri razširjenih regularnih izrazih pa povratne reference ne delujejo v vseh programih, ker niso standardizirane. Vendar z grepom delujejo, zato je to morda še en način, da to storimo. Lahko poskusite, če želite.

Nadomestni izrazi: ukaz sed

Poleg iskanja je ena najboljših načinov uporabe regularnih izrazov tudi zamenjava zapletenih besedil. To lahko naredite z ukazom sed. Moč ukaza sed daleč presega nadomeščanje besedila, toda tukaj ga bom uporabil za to. Sintaksa, ki jo bom uporabil s tem ukazom, je naslednja:

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

Ali tudi:

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

Kjer bo REGEX iskalni regularni izraz, REPL pa nadomestni. Upoštevajte, da ta ukaz v resnici ne nadomesti ničesar v datoteki, ki smo jo navedli, ampak nam pokaže rezultat zamenjave v terminalu, zato se ne ustrašite ukazov, ki jih bom dal naslednji. Nobeden od njih ne bo spreminjal datotek v vašem sistemu.

Začnimo s preprostim primerom. Vsi imamo v imeniku / etc različne konfiguracijske datoteke, ki imajo ponavadi komentarje, ki se začnejo z "#". Recimo, da želimo videti eno od teh datotek brez komentarjev. Na primer, to bom naredil s fstab. Lahko poskusite s tistim, ki ga želite.

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

Rezultata ukaza ne bom postavil sem, ker je to odvisno od tega, kaj imate v fstabu, toda če primerjate rezultat ukaza z vsebino datoteke, boste videli, da so vsi komentarji izginili.

V tem ukazu je iskalni izraz «#.*", To je" # ", ki mu sledi poljubno število znakov, to je komentarji. In nadomestni izraz, če pogledate dve vrstici zapored, boste videli, da jih ni, torej to, kar počne, je zamenjava komentarjev z ničemer, to je njihovo brisanje. Preprosteje nemogoče.

Zdaj bomo storili ravno nasprotno. Recimo, da želimo komentirati vse vrstice datoteke. Poskusimo takole:

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

Videli boste, da se v izhodu ukaza vse vrstice začnejo z oznako zgoščevanja in praznim prostorom. Kar smo storili, je zamenjati začetek vrstice z «# «. To je tudi dokaj preprost primer, ko je besedilo, ki ga je treba zamenjati, vedno enako, zdaj pa ga bomo še bolj zakomplicirali.

Milost nadomestkov je, da lahko v izrazu za nadomestitev uporabite povratne reference, kakršne sem vam že povedal. Vrnimo se k besedni datoteki, ki smo jo prenesli na začetek članka. V oklepaje bomo postavili vse velike tiskane črke, vendar bomo to storili z ukazom:

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

Tukaj imamo povratno referenco v nadomestnem izrazu, ki se nanaša na oklepaje v iskalnem izrazu. Oklepaji v nadomestnem izrazu so običajni oklepaji. V nadomestnem izrazu nimajo posebnega pomena, vstavljeni so kot so. Rezultat tega je, da se vse velike tiskane črke nadomestijo z isto črko, kakršna koli že je, z oklepaji okoli nje.

V nadomestnem izrazu je mogoče uporabiti še en znak, ki je "&" in ga nadomesti celotno besedilo, ki se ujema z iskalnim izrazom. Primer tega je lahko postavitev vseh besednih zvez v datoteko v narekovaje. To lahko dosežemo s tem ukazom:

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

Delovanje tega ukaza je zelo podobno prejšnjemu, le da zdaj nadomestimo celotno vrstico z isto vrstico z narekovaji okoli nje. Ker uporabljamo "&", ni treba vstaviti oklepajev.

Nekaj ​​uporabnih ukazov z regularnimi izrazi

Tu je nekaj ukazov, ki se mi zdijo koristni ali radovedni in ki uporabljajo regularne izraze. S temi ukazi je koristnost regularnih izrazov veliko boljša kot pri primerih, ki sem jih navedel do zdaj, vendar se mi je zdelo pomembno, da pojasnim nekaj o tem, kako regularni izrazi delujejo, da jih razumem.

  • Prikaži razdelke strani z navodili:

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

Seveda lahko ukaz bash spremenite v karkoli želite. In potem od človeka lahko greste neposredno v razdelek, ki vas zanima, seveda z običajnim izrazom. Pritisnite «/», da začnete iskati in pisati «^ALIASES$»Na primer, da greste v razdelek NIKONICE. Mislim, da je to prva uporaba regularnih izrazov, ki sem jo začel uporabljati pred nekaj leti. Premikanje po nekaterih straneh priročnika je skoraj nemogoče brez takšnega trika.

  • Pokažite imena vseh uporabnikov stroja, vključno s posebnimi:

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

  • Pokaži uporabniška imena, vendar samo tista z lupino:

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

Res je mogoče to storiti z enim regularnim izrazom, vendar način, kako to storiti, presega tisto, kar sem vam povedal v teh člankih, zato sem to storil s kombiniranjem dveh ukazov.

  • Pred zadnjimi tremi števkami vseh števil v datoteko s številkami vstavite vejico:

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

Deluje samo s številkami do 6 števk, vendar ga lahko večkrat pokličemo, da ločila umestimo v druge skupine s tremi števkami.

  •  Iz datoteke izvlecite vse e-poštne naslove:

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

  • Ločite dan, mesec in leto vseh datumov, ki so prikazani v datoteki:

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

  • Poiščite naš lokalni IP:

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

To je mogoče storiti tudi z enim ukazom sed, vendar ga zaradi enostavnosti bolje ločim na grep in sed.

Nekaj ​​uporabnih naslovov

Tu je nekaj naslovov, ki so lahko koristni v zvezi z regularnimi izrazi:

  • Knjižnica regularnih izrazov: To je knjižnica regularnih izrazov, v kateri lahko iščete regularne izraze, povezane s temo, ki vas zanima. Za iskanje spletnih naslovov, ID ali kar koli drugega.
  • RegExr: Spletni pregledovalnik regularnih izrazov. Omogoča vam, da vnesete besedilo in mu uporabite regularni izraz, bodisi poiščite ali zamenjajte. Daje informacije o regularnem izrazu in imate nekaj možnosti, da spremenite njegovo vedenje.
  • Tester regularnih izrazov: Je dodatek za firefox, ki omogoča preverjanje regularnih izrazov iz brskalnika.

Zaključek

Za zdaj je to vse. Regularni izrazi so zapleteni, a uporabni. Potreben je čas, da se jih naučite, toda če ste takšni kot jaz, se bo igranje z njimi zdelo zabavno in jih boste po malem obvladali. To je cel svet. Še veliko bi lahko povedali o lenih kvantifikatorjih, regularnem izrazu v stilu PERL, večvrstičnem itd. In potem ima vsak program svoje značilnosti in svoje različice, zato je najboljši nasvet, ki vam ga lahko dam, da si vedno ogledate dokumentacijo programa, ki ga uporabljate, vsakič, ko morate v nov program napisati regularni izraz.

Zdravo! …ZDRAVO! … ZBUDI SE! ... KAJ VSI SPIJO? 🙂

Fuentes

Nekaj ​​idej in primerov za regularne izraze v tem članku sem vzel od tukaj:


Pustite svoj komentar

Vaš e-naslov ne bo objavljen. Obvezna polja so označena z *

*

*

  1. Za podatke odgovoren: Miguel Ángel Gatón
  2. Namen podatkov: Nadzor neželene pošte, upravljanje komentarjev.
  3. Legitimacija: Vaše soglasje
  4. Sporočanje podatkov: Podatki se ne bodo posredovali tretjim osebam, razen po zakonski obveznosti.
  5. Shranjevanje podatkov: Zbirka podatkov, ki jo gosti Occentus Networks (EU)
  6. Pravice: Kadar koli lahko omejite, obnovite in izbrišete svoje podatke.

  1.   živahno je dejal

    Mojster !!!

    1.    Hexborg je dejal

      Ni tako hudo, ampak najlepša hvala. Upam, da je ljudem všeč. 🙂

      1.    Oscar je dejal

        Všeč mi je ha!

        1.    Hexborg je dejal

          Potem sem moral nekaj narediti prav. LOL !! 🙂

          Najlepša hvala za vaš komentar.

          1.    Blaire pascal je dejal

            Jebi se, piši naprej, človek, tako nadaljuj.

          2.    Hexborg je dejal

            @Blaire Pascal: Komentarji, kakršen je tvoj, to spodbujajo. 🙂 najlepša hvala !!

      2.    Mesto je dejal

        Všeč mi je bilo tudi ... hvala 🙂

        1.    Hexborg je dejal

          Hvala za komentar. Upam, da bom napisal še nekaj. 🙂

  2.   mariano je dejal

    Vaše objave so fantastične, veliko se naučite, naučite se opravljati naloge na eleganten in učinkovit način.

    Ste razmišljali o tem, da bi zbrali vse objave v skriptu? Razvrščeno v pdf bi bilo odličen priročnik.

    Razvedri se in najlepša hvala!

    1.    Hexborg je dejal

      Najlepša hvala!! Ni slaba ideja. Trenutno sta le dva, vendar bom o tem razmislil kasneje. 🙂

  3.   Kiyov je dejal

    zelo dober članek, 5+.

    1.    Hexborg je dejal

      Hvala vam. Vesel sem, da vam je všeč. 🙂

  4.   Sebastian je dejal

    Odlično! Spremeniti moram naslednji izraz in ne vem, kako to storiti:
    192.168.0.138/Server z 192.168.0.111/data
    Težava je v simbolu "/".
    Uporabljam ukaz:
    najti. -ime "* .txt" -exec sed -i 's / TEXT1 / TEXT2 / g' {} \;
    Kaj se uporablja za to vrsto opravil z zapuščanjem, vendar ne morem ...
    Ali kdo ve, kako naj to storim?
    Objem!
    Seba

    1.    Hexborg je dejal

      Kar morate storiti, je pobegniti iz lika, kot je ta:

      najti. -ime "* .txt" -exec sed -i 's / \ / Server / \ / data / g' {} \;

      Uporabite lahko tudi drugo ločilo v sed. Ni nujno, da je točilnica. Sed dovoljuje uporabo katerega koli znaka. To bi bilo na primer bolj jasno:

      najti. -ime "* .txt" -exec sed -i '| | / Server | / data | g' {} \;

      Če želite kopirati in prilepiti ukaze iz tega komentarja, bodite previdni pri narekovajih, saj jih Wordpress spremeni za tipografske. 🙂

      Lep pozdrav.

  5.   Sebastian je dejal

    Odlično !!!!
    To rešitev iščem že dolgo.
    Tu pustim celoten ukaz, ki sem ga uporabil

    najti. -ime "* .txt" -exec sed -i 's | 192 \ .168 \ .0 \ .238 \ / Server | 192 \ .168 \ .0 \ .111 \ / data | g' {} \;

    Prednost tega ukaza je, da rekurzivno spremeni vse datoteke .txt (ali končnico, ki jo želite) ... Bodite zelo previdni!
    Je pa zelo koristno !!!

    No, hvala za vse in tisoč čestitk celotni skupini.
    Vedno jih berem po pošti!
    Objemi
    Seba