În mine anterioară articol V-am spus la un nivel de bază cum funcționează fiecare dintre cele mai utilizate caractere speciale ale expresiilor regulate. Cu aceste expresii regulate este posibil să faceți căutări complexe în fișiere text sau în ieșirea altor comenzi. În acest articol voi explica cum să folosesc comanda sed pentru a găsi și înlocui textul într-un mod mult mai puternic decât simpla schimbare a unui text cu altul.
Un pic mai mult despre comanda grep
Înainte de a începe să vorbesc despre sed, aș dori să comentez un pic mai mult despre comanda grep pentru a completa puțin ceea ce a fost explicat în articolul precedent. Tot ce voi spune va fi relevant și pentru acesta. Mai târziu vom vedea relația dintre aceasta și căutări.
Combinând expresii regulate
Multe dintre personajele speciale despre care am vorbit în articolul anterior pot fi combinate, nu numai cu alte personaje, ci cu expresii regulate întregi. Modul de a face acest lucru este de a utiliza paranteze pentru a forma o subexpresie. Să vedem un exemplu în acest sens. Să începem prin descărcarea unui text pe care îl putem folosi pentru testare. Este o listă de fraze. Pentru aceasta vom folosi următoarea comandă:
curl http://artigoo.com/lista-de-frases-comparativas-comicas 2>/dev/null | sed -n 's/.*\(.*\.\)<\/p>/\1/gp' > frases
Acest lucru vă va lăsa în directorul în care îl lansați un fișier cu numele „fraze”. Îl poți deschide pentru a arunca o privire și a râde puțin.
Acum să presupunem că vrem să găsim expresiile care au exact 6 cuvinte. Dificultatea constă în formarea unei expresii regulate care se potrivește cu fiecare cuvânt. Un cuvânt este o secvență de litere, fie majuscule, fie minuscule, care ar fi ceva de genul '[a-zA-Z]+', dar trebuie, de asemenea, să specificați că aceste litere trebuie separate de alte caractere decât litere, adică ar fi ceva de genul '[a-zA-Z]+[^a-zA-Z]+'. Amintiți-vă: „^” ca primul caracter din paranteze indică faptul că dorim să ne potrivim cu caractere care nu sunt în intervale și „+” indică 1 sau mai multe caractere.
Avem deja o expresie regulată care se poate potrivi cu un cuvânt. Pentru a-l împerechea cu 6, va trebui repetat de 6 ori. Pentru asta am folosit tastele, dar este inutil să punem '[a-zA-Z]+[^a-zA-Z]+{6}', deoarece 6 ar repeta ultima parte a expresiei regulate și ceea ce vrem este să repetăm totul, deci ceea ce trebuie să puneți este următorul: '([a-zA-Z]+[^a-zA-Z]+){6}'. Cu parantezele formăm o subexpresie și cu bretele o repetăm de 6 ori. Acum trebuie doar să adăugați un „^” în față și un „$” în spate pentru a se potrivi cu întreaga linie. Comanda este după cum urmează:
grep -E '^([a-zA-Z]+[^a-zA-Z]+){6}$' frases
Iar rezultatul este exact ceea ce ne-am dorit:
Este mai mult cântat decât Macarena. Ești mai terminat decât Luis Aguilé. Ai mai puțină cultură decât o piatră. Știi mai multe limbi decât Cañita Brava. Are mai multe riduri decât Tutan Khamón. Știi mai puțin decât Rambo despre îngrijirea copiilor.
Observați că am pus parametrul -E pentru că dorim să folosim expresii regulate extinse pentru a face ca „+” să funcționeze. Dacă le-am folosi pe cele de bază, ar trebui să scăpăm de paranteze și bretele.
Referințe înapoi sau referințe înapoi
Dacă aveți instalat un verificator ortografic, probabil că veți avea o listă de cuvinte în /usr/share/dict/words. Dacă nu, îl puteți instala în arc cu:
sudo pacman -S words
Sau în debian cu:
sudo aptitude install dictionaries-common
Dacă doriți, puteți arunca o privire la fișier pentru a vedea ce cuvinte are. De fapt, este un link către fișierul cuvânt al limbii în care se află distribuția dvs. Puteți avea mai multe fișiere word instalate în același timp.
Vom folosi acel fișier. Se pare că suntem foarte curioși să cunoaștem toți palindromii de șapte litere de acolo. Pentru cei care nu știu: Un palindrom este un cuvânt capicúa, adică poate fi citit de la stânga la dreapta, precum și de la dreapta la stânga. Să încercăm următoarea comandă:
grep '^\(.\)\(.\)\(.\).\3\2\1$' /usr/share/dict/words
Pare cam ciudat, nu? Dacă îl încercăm, rezultatul va depinde de limba distribuției dvs. și de cuvintele din lista dvs., dar în cazul meu, cu limba spaniolă, rezultatul este acesta:
anilină anilină rulare
Să vedem cum funcționează această expresie regulată.
În afară de „^” și „$”, pentru care știm deja la ce servește, primul lucru pe care îl vedem în stânga sunt trei grupuri de puncte închise între paranteze. Nu vă lăsați confundați de barele din fața fiecărei paranteze. Ei trebuie să scape de paranteze, deoarece folosim expresii regulate de bază, dar nu au altă semnificație. Important este că cerem trei caractere cu puncte, dar fiecare dintre aceste puncte este inclus între paranteze. Aceasta este pentru a salva caracterele care se potrivesc cu aceste puncte, astfel încât să poată fi referite din nou din expresia regulată. Aceasta este o altă utilizare a parantezelor care va fi utilă mai târziu în efectuarea înlocuirilor.
Aici vin cele trei numere de mai jos cu bară în fața lor. În acest caz, bara este importantă. Este folosit pentru a indica faptul că numărul de mai jos este o referință inversă și se referă la una dintre parantezele anterioare. De exemplu: \ 1 se referă la prima paranteză, \ 2 la a doua și așa mai departe.
Adică, cu expresia regulată pe care am pus-o, ceea ce căutăm sunt toate cuvintele care încep cu oricare patru litere și apoi au o literă care este la fel ca a treia, alta care este la fel ca a doua și alta același lucru ca primul. Rezultatul este palindromul de șapte litere care se află în lista de cuvinte. Așa cum am vrut.
Dacă am folosi expresii regulate extinse, parantezele nu ar trebui să fie evadate, dar cu expresii regulate extinse, referințele inversă nu funcționează în toate programele, deoarece nu sunt standardizate. Cu toate acestea, cu grep funcționează, astfel încât acesta poate fi un alt mod de a face același lucru. Puteți încerca dacă doriți.
Expresii de înlocuire: comanda sed
Pe lângă căutare, una dintre cele mai bune utilizări ale expresiilor regulate este înlocuirea textelor complexe. Pentru a face acest lucru, o modalitate de a face acest lucru este cu comanda sed. Puterea comenzii sed depășește cu mult înlocuirea textului, dar aici îl voi folosi pentru asta. Sintaxa pe care o voi folosi cu această comandă este următoarea:
sed [-r] 's/REGEX/REPL/g' FICHERO
Sau, de asemenea:
COMANDO | sed [-r] 's/REGEX/REPL/g'
În cazul în care REGEX va fi expresia regulată de căutare și REPL cea de înlocuire. Rețineți că această comandă nu înlocuiește cu adevărat nimic din fișierul pe care îl indicăm, dar ceea ce face este să ne arate rezultatul înlocuirii în terminal, așa că nu vă speriați de comenzile pe care le voi pune în continuare. Niciunul dintre ei nu va modifica niciun fișier din sistemul dvs.
Să începem cu un exemplu simplu. Cu toții avem diverse fișiere de configurare în directorul / etc care au de obicei comentarii începând cu „#”. Să presupunem că vrem să vedem unul dintre aceste fișiere fără comentarii. De exemplu, o voi face cu fstab. Puteți încerca cu cea dorită.
sed 's/#.*//g' /etc/fstab
Nu voi pune rezultatul comenzii aici, deoarece depinde de ceea ce aveți în fstab, dar dacă comparați ieșirea comenzii cu conținutul fișierului, veți vedea că toate comentariile au dispărut.
În această comandă, expresia de căutare este «#.*", Acesta este un" # "urmat de orice număr de caractere, adică comentarii. Și expresia de înlocuire, dacă te uiți la cele două bare la rând, vei vedea că nu există, așa că ceea ce face este să înlocuiești comentariile cu nimic, adică să le ștergi. Mai simplu imposibil.
Acum vom face contrariul. Să presupunem că ceea ce dorim este să comentăm toate liniile fișierului. Să încercăm așa:
sed 's/^/# /g' /etc/fstab
Veți vedea că, în ieșirea comenzii, toate liniile încep cu un semn hash și un spațiu gol. Ceea ce am făcut este să înlocuim începutul rândului cu «# «. Acesta este, de asemenea, un exemplu destul de simplu în care textul care trebuie înlocuit este întotdeauna același, dar acum îl vom complica un pic mai mult.
Grația înlocuirilor este că, în expresia de înlocuire, puteți utiliza referințe inversă, precum cele pe care vi le-am spus înainte. Să ne întoarcem la fișierul expresie pe care l-am descărcat la începutul articolului. Vom pune între paranteze toate literele majuscule care există, dar o vom face cu o comandă:
sed 's/\([A-Z]\)/(\1)/g' frases
Ceea ce avem aici este o referință inversă în expresia de înlocuire care se referă la parantezele din expresia de căutare. Parantezele din expresia de înlocuire sunt paranteze normale. În expresia de înlocuire nu au o semnificație specială, sunt așa cum este. Rezultatul este că toate literele majuscule sunt înlocuite cu aceeași literă, oricare ar fi aceasta, cu paranteze în jurul ei.
Există un alt caracter care poate fi folosit și în expresia de înlocuire, este „&” și este înlocuit cu tot textul asociat cu expresia de căutare. Un exemplu în acest sens ar putea fi punerea tuturor frazelor din fișier între ghilimele. Acest lucru poate fi realizat cu această comandă:
sed 's/.*/"&"/g' frases
Funcționarea acestei comenzi este foarte asemănătoare cu cea precedentă, doar că acum ceea ce înlocuim este întreaga linie cu aceeași linie cu ghilimele în jurul său. Deoarece folosim „&”, nu este necesar să punem paranteze.
Câteva comenzi utile cu expresii regulate
Iată câteva comenzi care mi se par utile sau curioase și care folosesc expresii regulate. Cu aceste comenzi utilitatea expresiilor regulate este mult mai bună decât cu exemplele pe care vi le-am dat până acum, dar mi s-a părut important să explic ceva despre modul în care funcționează expresiile regulate pentru a le înțelege.
- Afișați secțiunile unei pagini de manual:
man bash | grep '^[A-Z][A-Z ]*$'
Desigur, puteți schimba comanda bash la orice doriți. Și apoi de la om, puteți merge direct la secțiunea care vă interesează folosind, desigur, o expresie regulată. Apăsați «/» pentru a începe să căutați și să scrieți «^ALIASES$»Pentru a merge la secțiunea ALIASES, de exemplu. Cred că aceasta este prima utilizare pe care am început să o fac cu expresiile regulate acum câțiva ani. Deplasarea prin unele pagini ale manualului este aproape imposibilă fără un truc ca acesta.
- Afișați numele tuturor utilizatorilor mașinii, inclusiv cele speciale:
sed 's/\([^:]*\).*/\1/' /etc/passwd
- Afișați numele de utilizator, dar numai cele cu shell:
grep -vE '(/false|/nologin)$' /etc/passwd | sed 's/\([^:]*\).*/\1/g'
Se poate face într-adevăr cu o singură expresie regulată, dar modul în care o poți face depășește ceea ce ți-am spus în aceste articole, așa că am făcut-o combinând două comenzi.
- Introduceți o virgulă înaintea ultimelor trei cifre ale tuturor numerelor din fișierul numerelor:
sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers
Funcționează numai cu numere de până la 6 cifre, dar poate fi apelat de mai multe ori pentru a plasa separatoare în celelalte grupuri de trei cifre.
- Extrageți toate adresele de e-mail dintr-un fișier:
grep -E '\<[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\>' FICHERO
- Separați ziua, luna și anul de toate datele care apar într-un fișier:
sed -r 's/([0-9]{2})[/-]([0-9]{2})[/-]([0-9]{4})/Día: \1, Mes: \2, Año: \3/g' FICHERO
- Aflați IP-ul nostru local:
/sbin/ifconfig | grep 'inet .*broadcast' | sed -r 's/[^0-9]*(([0-9]+\.){3}[0-9]+).*/\1/g'
Acest lucru se poate face și cu o singură comandă sed, dar mai bine o separ într-un grep și un sed pentru simplitate.
Câteva adrese utile
Iată câteva adrese care pot fi utile legate de expresiile regulate:
- Biblioteca de expresie regulată: Aceasta este o bibliotecă de expresii regulate în care puteți căuta expresii regulate legate de subiectul care vă interesează. Pentru a căuta adrese web, ID sau orice altceva.
- RegExr: Un verificator de expresii regulate online. Vă permite să introduceți un text și să aplicați o expresie obișnuită, fie căutați, fie înlocuiți. Oferă informații despre expresia regulată și aveți câteva opțiuni pentru a-i schimba comportamentul.
- Tester de expresii regulate: Este un addon pentru Firefox care permite verificarea expresiilor regulate din browser.
Concluzie
Deocamdată asta e tot. Expresiile regulate sunt complexe, dar utile. Îți ia timp să-i înveți, dar dacă ești ca mine, jocul cu ei va părea distractiv și, încetul cu încetul, îi vei stăpâni. Este o lume întreagă. Ar fi încă multe de spus, despre cuantificatoarele leneșe, regex în stil PERL, multilinie etc. Și apoi fiecare program are caracteristicile și variantele sale, așa că cel mai bun sfat pe care îl pot oferi este să te uiți întotdeauna la documentația programului pe care îl folosești de fiecare dată când trebuie să scrii o expresie regulată într-un nou program.
Hei! …HEI! …TREZEŞTE-TE! …CE FACEȚI VOI TOȚI ÎN CAZUL DORMIȚI?
surse
Unele dintre ideile și exemplele pentru expresii regulate din acest articol le-am luat de aici:
- http://sed.sourceforge.net/sed1line.txt
- http://www.thegeekstuff.com/2009/10/unix-sed-tutorial-advanced-sed-substitution-examples/