Ar termināli: izmantojot regulārās izteiksmes II: aizstājēji

Sevī iepriekšējais raksts Es jums pamatlīmenī esmu teicis, kā darbojas katrs no regulāro izteicienu visbiežāk izmantotajiem īpašajiem rakstzīmēm. Ar šīm regulārajām izteiksmēm ir iespējams veikt sarežģītus meklējumus teksta failos vai citu komandu izvadā. Šajā rakstā es izskaidrošu, kā izmantot komandu sed, lai atrastu un aizstātu tekstu daudz spēcīgāk, nekā vienkārši nomainot vienu tekstu pret citu.

Nedaudz vairāk par grep komandu

Pirms sāku runāt par sed, es vēlētos nedaudz vairāk komentēt komandu grep, lai mazliet papildinātu iepriekšējā rakstā izskaidroto. Viss, ko es teikšu, būs aktuāls arī šim. Vēlāk mēs redzēsim attiecības starp šo un meklējumiem.

Regulāru izteicienu apvienošana

Daudzas īpašās rakstzīmes, par kurām esmu runājis iepriekšējā rakstā, var apvienot ne tikai ar citām rakstzīmēm, bet ar veselām regulārām izteiksmēm. Veids, kā to izdarīt, ir iekavu izmantošana, lai izveidotu apakšizteiksmi. Apskatīsim šī piemēru. Sāksim ar teksta lejupielādi, kuru varam izmantot testēšanai. Tas ir frāžu saraksts. Tam mēs izmantosim šādu komandu:

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

 Tādējādi jūs paliksit direktorijā, kurā palaidīsit failu ar nosaukumu «frāzes». Jūs varat to atvērt, lai paskatītos un nedaudz pasmieties. 🙂

Tagad pieņemsim, ka mēs vēlamies atrast frāzes, kurās ir tieši 6 vārdi. Grūtības ir izveidot regulāru izteiksmi, kas atbilst katram vārdam. Vārds ir lielo vai mazo burtu secība, kas būtu kaut kas līdzīgs '[a-zA-Z]+', bet jums arī jānorāda, ka šie burti ir jāatdala ar citām rakstzīmēm, nevis burtiem, tas ir, tas būtu kaut kas līdzīgs '[a-zA-Z]+[^a-zA-Z]+'. Atcerēsimies: "^" kā pirmā rakstzīme iekavās norāda, ka mēs vēlamies saskaņot ar rakstzīmēm, kas nav diapazonos, un "+" norāda 1 vai vairāk rakstzīmes.

Mums jau ir regulāra izteiksme, kas var atbilst vārdam. Lai to savienotu pārī ar 6, tas būs jāatkārto 6 reizes. Tam mēs izmantojām atslēgas, bet to ir bezjēdzīgi likt '[a-zA-Z]+[^a-zA-Z]+{6}', jo 6 atkārtotu regulārās izteiksmes pēdējo daļu, un tas, ko mēs vēlamies, ir atkārtot visu, tāpēc mums ir jāievieto tas: '([a-zA-Z]+[^a-zA-Z]+){6}'. Ar iekavām mēs veidojam apakšizteiksmi un ar lencēm mēs to atkārtojam 6 reizes. Tagad jums vienkārši jāpievieno "^" priekšā un "$" aizmugurē, lai tie atbilstu visai līnijai. Komanda ir šāda:

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

Rezultāts ir tieši tas, ko mēs vēlējāmies:

Tas ir vairāk dziedāts nekā Macarena. Jūs esat vairāk pabeigts nekā Luiss Agilē. Jums ir mazāk kultūras nekā akmenim. Jūs zināt vairāk valodu nekā Cañita Brava. Viņam ir vairāk grumbu nekā Tutanam Hamonam. Par bērnu aprūpi jūs zināt mazāk nekā Rambo.

Ievērojiet, ka mēs ievietojam parametru -E, jo mēs vēlamies izmantot paplašinātās regulārās izteiksmes, lai "+" darbotos. Ja mēs izmantotu pamata, mums vajadzētu izvairīties no iekavām un lencēm.

Atsauces uz aizmuguri vai atsauces

Ja jums ir instalēta pareizrakstības pārbaude, iespējams, jums būs vārdu saraksts /usr/share/dict/words. Ja nē, varat to instalēt arhā ar:

sudo pacman -S words

Vai debiānā ar:

sudo aptitude install dictionaries-common

Ja vēlaties, varat apskatīt failu, lai redzētu, kādi vārdi tajā ir. Patiesībā tā ir saite uz valodas failu, kurā atrodas jūsu izplatītājs. Vienlaikus var būt instalēti vairāki vārdu faili.

Mēs izmantosim šo failu. Izrādās, ka mums ir ļoti interesanti uzzināt visus tur esošos septiņu burtu palindromus. Tiem, kas nezina: palindroms ir vārds capicúa, tas ir, to var lasīt gan no kreisās uz labo pusi, gan no labās uz kreiso. Izmēģināsim šādu komandu:

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

Tas izskatās mazliet dīvaini, vai ne? Ja mēs to izmēģināsim, rezultāts būs atkarīgs no jūsu izplatītāja valodas un vārdiem, kas ir jūsu sarakstā, bet manā gadījumā ar spāņu valodu rezultāts ir šāds:

anilīna anilīna velmēšana

Apskatīsim, kā darbojas šī regulārā izteiksme.

Izņemot “^” un “$”, par kuriem mēs jau zinām, kam tas ir domāts, pirmā lieta, ko redzam kreisajā pusē, ir trīs punktu grupas, kas ieslēgtas iekavās. Nejauciet joslas katras iekavas priekšā. Viņiem jāizvairās no iekavām, jo ​​mēs izmantojam regulāras pamata izteiksmes, taču tām nav citas nozīmes. Svarīgi ir tas, ka mēs lūdzam jebkuras trīs rakstzīmes ar punktiem, bet katrs no šiem punktiem ir iekavās. Tas ir paredzēts, lai saglabātu rakstzīmes, kas atbilst šiem punktiem, lai uz tām atkal varētu atsaukties no parastās izteiksmes. Šī ir vēl viena iekavu izmantošana, kas vēlāk noderēs, lai veiktu aizstājējus.

Šeit ir trīs tālāk minētie skaitļi ar slīpsvītru priekšā. Šajā gadījumā josla ir svarīga. To lieto, lai norādītu, ka zemāk redzamais skaitlis ir atsauce un attiecas uz kādu no iepriekšējām iekavām. Piemēram: \ 1 attiecas uz pirmo iekavu, \ 2 uz otro utt.

Tas ir, ar mūsu izveidoto regulāro izteiksmi mēs meklējam visus vārdus, kas sākas ar jebkuriem četriem burtiem un pēc tam ir burts, kas ir tāds pats kā trešais, cits ir tāds pats kā otrais un cits, kas ir tāds pats kā vispirms. Rezultāts ir septiņu burtu palindromi, kas atrodas vārdu sarakstā. Tāpat kā mēs vēlējāmies.

Ja mēs izmantotu paplašinātas regulāras izteiksmes, iekavas nebūtu jāizvairās, bet ar paplašinātām regulārām izteiksmēm atsauces nedarbojas visās programmās, jo tās nav standartizētas. Tomēr ar grep viņi strādā, tāpēc tas var būt vēl viens veids, kā darīt to pašu. Ja vēlaties, varat to izmēģināt.

Aizstāšanas izteicieni: komanda sed

Papildus meklēšanai viens no labākajiem regulāro izteicienu izmantošanas veidiem ir sarežģītu tekstu aizstāšana. Lai to izdarītu, viens veids, kā to izdarīt, ir komanda sed. Komandas sed spēks pārsniedz tekstu aizstāšanu, bet šeit es to izmantoju. Sintakse, kuru es izmantošu ar šo komandu, ir šāda:

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

Vai arī:

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

Kur REGEX būs meklēšanas regulārā izteiksme un REPL aizstājējvārdu. Paturiet prātā, ka šī komanda patiešām neaizstāj neko failā, ko mēs norādām, bet tas, kas tas tiek darīts, mums parāda termināļa nomaiņas rezultātu, tāpēc nebaidieties no komandām, kuras es ievietošu nākamajā. Neviens no viņiem negrasās modificēt nevienu failu jūsu sistēmā.

Sāksim ar vienkāršu piemēru. Mums visiem direktorijā / etc ir dažādi konfigurācijas faili, kuros parasti ir komentāri, kas sākas ar "#". Pieņemsim, ka mēs vēlamies redzēt vienu no šiem failiem bez komentāriem. Piemēram, es to darīšu ar fstab. Jūs varat izmēģināt ar vēlamo.

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

Es negrasos šeit likt komandas rezultātu, jo tas ir atkarīgs no tā, kas jums ir jūsu fstab, bet, ja jūs salīdzināt komandas izvadi ar faila saturu, jūs redzēsiet, ka visi komentāri ir pazuduši.

Šajā komandā meklēšanas izteiksme ir «#.*", Tas ir" # ", kam seko jebkurš rakstzīmju skaits, tas ir, komentāri. Un aizstāšanas izteiksme, ja paskatās uz divām joslām pēc kārtas, redzēs, ka tādu nav, tāpēc tas, ko tā dara, aizstāj komentārus ar neko, tas ir, tos dzēš. Vienkāršāk neiespējami.

Tagad mēs rīkosimies tieši pretēji. Pieņemsim, ka mēs vēlamies komentēt visas faila rindas. Mēģināsim šādi:

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

Jūs redzēsiet, ka komandas izvadē visas rindas sākas ar jaucējzīmi un tukšu vietu. Tas, ko mēs esam izdarījuši, ir aizstāt rindas sākumu ar «# «. Šis ir arī diezgan vienkāršs piemērs, kad aizstājamais teksts vienmēr ir vienāds, bet tagad mēs to nedaudz sarežģīsim.

Aizvietotāju žēlastība ir tāda, ka aizstājējteikumā varat izmantot tādas atsauces kā tās, kuras es jums teicu iepriekš. Atgriezīsimies pie frāzes faila, kuru lejupielādējām raksta sākumā. Mēs iekavās ievietosim visus lielos burtus, kas ir, bet mēs to darīsim ar komandu:

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

Mums šeit ir atsauce uz aizstājējteikumu, kas attiecas uz iekavām meklēšanas izteiksmē. Iekavas aizstāšanas izteiksmē ir normālas iekavas. Aizstāšanas izteiksmē tiem nav īpašas nozīmes, tie tiek likti tādi, kādi tie ir. Rezultātā visi lielie burti tiek aizstāti ar to pašu burtu, lai kāds tas būtu, ap iekavām.

Ir vēl viena rakstzīme, kuru var izmantot arī aizstājējteikumā, tas ir "&", un to aizstāj ar visu tekstu, kas atbilst meklēšanas izteiksmei. Piemērs tam varētu būt visu failā esošo frāžu ievietošana pēdiņās. To var panākt ar šo komandu:

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

Šīs komandas darbība ir ļoti līdzīga iepriekšējai, tikai tagad mēs aizstājam visu līniju ar to pašu rindu ar pēdiņām ap to. Tā kā mēs izmantojam "&", nav nepieciešams ievietot iekavas.

Dažas noderīgas komandas ar regulārām izteiksmēm

Šeit ir dažas komandas, kuras man šķiet noderīgas vai ziņkārīgas un kurās tiek izmantotas regulāras izteiksmes. Izmantojot šīs komandas, parasto izteiksmju lietderība ir daudz labāka nekā ar piemēriem, kurus es jums līdz šim esmu devis, taču šķita svarīgi kaut ko izskaidrot par regulāro izteicienu darbību, lai tos saprastu.

  • Rādīt cilvēka lapas sadaļas:

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

Protams, jūs varat mainīt komandu bash uz visu, ko vēlaties. Un tad no cilvēka jūs varat doties tieši uz sadaļu, kas jūs interesē, izmantojot, protams, regulāru izteiksmi. Nospiediet «/», lai sāktu meklēt un rakstītu «^ALIASES$»Lai pārietu, piemēram, uz sadaļu ALIASES. Es domāju, ka tas ir pirmais regulāro izteicienu lietojums, ko sāku lietot pirms dažiem gadiem. Pārvietoties pa dažām rokasgrāmatas lappusēm bez šāda trika ir gandrīz neiespējami.

  • Parādiet visu mašīnas lietotāju vārdus, ieskaitot īpašos:

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

  • Rādīt lietotājvārdus, bet tikai tos, kuriem ir apvalks:

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

To patiešām var izdarīt ar vienu regulāru izteiksmi, taču veids, kā to izdarīt, pārsniedz to, ko es jums teicu šajos rakstos, tāpēc esmu to izdarījis, apvienojot divas komandas.

  • Ievietojiet komatu pirms skaitļu failā esošo skaitļu pēdējiem trim cipariem:

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

Tas darbojas tikai ar skaitļiem līdz 6 cipariem, bet to var izsaukt vairāk nekā vienu reizi, lai atdalītājus ievietotu pārējās trīs ciparu grupās.

  •  Izvilkt no faila visas e-pasta adreses:

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

  • Atdaliet datumu, mēnesi un gadu no visiem datumiem, kas tiek parādīti failā:

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

  • Uzziniet mūsu vietējo IP:

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

To var izdarīt arī ar vienu sed komandu, taču vienkāršības labad es labāk to nošķiru grep un sed.

Dažas noderīgas adreses

Šeit ir dažas adreses, kas var būt noderīgas saistībā ar regulārajām izteiksmēm:

  • Regulārās izteiksmes bibliotēka: Šī ir regulāru izteiksmju bibliotēka, kurā varat meklēt regulāras izteiksmes, kas saistītas ar tevi, kas jūs interesē. Lai meklētu tīmekļa adreses, ID vai jebkuru citu.
  • RegExr: Tiešsaistes regulārās izteiksmes pārbaudītājs. Tas ļauj ievadīt tekstu un lietot regulāru izteiksmi, meklējot vai aizstājot. Tas sniedz informāciju par regulāro izteiksmi, un jums ir dažas iespējas mainīt tā uzvedību.
  • Regulāro izteiksmju testeris: Tas ir Firefox papildinājums, kas ļauj pārlūkprogrammā pārbaudīt regulāros izteicienus.

Secinājums

Pagaidām tas arī viss. Regulārās izteiksmes ir sarežģītas, bet noderīgas. Viņu apgūšana prasa laiku, taču, ja jūs esat līdzīgs man, spēlēšanās ar viņiem šķitīs jautra un pamazām jūs tos apgūsiet. Tā ir vesela pasaule. Vēl būtu daudz ko teikt, par slinkiem kvantoriem, PERL stila regexu, daudzrindu utt. Un tad katrai programmai ir savas īpatnības un tās varianti, tāpēc labākais padoms, ko es jums varu sniegt, ir vienmēr apskatīt programmas dokumentāciju, kuru izmantojat, katru reizi, kad jums ir jāraksta regulāra izteiksme jaunā programmā.

Hei! ... Hei! … CELIES! ... KO jūs visi gulējat? 🙂

Fuentes

Dažas no šī raksta regulāro izteicienu idejām un piemēriem esmu paņēmis šeit:


Atstājiet savu komentāru

Jūsu e-pasta adrese netiks publicēta. Obligātie lauki ir atzīmēti ar *

*

*

  1. Atbildīgais par datiem: Migels Ángels Gatóns
  2. Datu mērķis: SPAM kontrole, komentāru pārvaldība.
  3. Legitimācija: jūsu piekrišana
  4. Datu paziņošana: Dati netiks paziņoti trešām personām, izņemot juridiskus pienākumus.
  5. Datu glabāšana: datu bāze, ko mitina Occentus Networks (ES)
  6. Tiesības: jebkurā laikā varat ierobežot, atjaunot un dzēst savu informāciju.

  1.   dzīvīgs teica

    Meistarīgi !!!

    1.    Hexborg teica

      Tas nav tik slikti, bet liels paldies. Ceru, ka cilvēkiem tas patīk. 🙂

      1.    Oskars teica

        Man patīk ha!

        1.    Hexborg teica

          Tad es noteikti kaut ko esmu izdarījis pareizi. LOL !! 🙂

          Liels paldies par komentāru.

          1.    Blērs paskals teica

            Fuck turpini rakstīt cilvēks, tā turpināt.

          2.    Hexborg teica

            @Blaire Pascal: Tādi komentāri kā jūs, to mudina. 🙂 liels paldies !!

      2.    Pilsēta teica

        Man arī patika ... paldies 🙂

        1.    Hexborg teica

          Paldies par komentāru. Es ceru uzrakstīt vēl dažus. 🙂

  2.   marian teica

    Jūsu ziņas ir fantastiskas, jūs daudz iemācāties, drīzāk iemācāties eleganti un efektīvi veikt uzdevumus.

    Vai esat domājis par visu savu čaulas skriptu ziņu apkopošanu? Kārtojot pdf formātā, tā būtu lieliska rokasgrāmata.

    Uzmundrina un liels paldies!

    1.    Hexborg teica

      Liels paldies!! Tā nav slikta ideja. Šobrīd ir tikai divi, bet es par to domāju vēlāk. 🙂

  3.   Kijovs teica

    ļoti labs raksts, 5+.

    1.    Hexborg teica

      Paldies. Man prieks, ka tev patīk. 🙂

  4.   Sebastian teica

    Izcili! Man jāmaina šī izteiksme, un es nezinu, kā to izdarīt:
    192.168.0.138/Server ar 192.168.0.111/data
    Problēma slēpjas simbolā "/".
    Es izmantoju komandu:
    atrast. -nosaukums "* .txt" -exec sed -i 's / TEXT1 / TEXT2 / g' {} \;
    Kas tiek izmantots, lai šāda veida uzdevumus veiktu noraidoši, bet es nevaru ...
    Vai kāds zina, kā man tas būtu jādara?
    Apskāviens!
    Seba

    1.    Hexborg teica

      Kas jums jādara, ir izvairīties no šāda rakstura:

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

      Varat arī izmantot citu separatoru sed. Tam nav jābūt bāram. Sed ļauj izmantot jebkuru rakstzīmi. Piemēram, tas būtu skaidrāk:

      atrast. -nosaukums "* .txt" -exec sed -i s | / Server | / data | g '{} \;

      Un, ja jūs gatavojaties kopēt un ielīmēt komandas no šī komentāra, esiet uzmanīgs ar pēdiņām, ka WordPress tos maina pret tipogrāfiskajiem. 🙂

      Sveicieni.

  5.   Sebastian teica

    Izcili !!!!
    Es ilgi meklēju šo risinājumu.
    Šeit es atstāju visu komandu, kuru esmu izmantojis

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

    Šīs komandas priekšrocība ir tā, ka tā rekursīvi maina visus .txt failus (vai nepieciešamo paplašinājumu) ... Jums jābūt ļoti uzmanīgam!
    Bet tas ir ļoti noderīgi !!!

    Nu, paldies par visu un tūkstoš apsveikumi visai grupai.
    Es vienmēr tos lasu no pasta!
    Apskāvieni
    Seba