Weekend Prosjekt: Intro til hjelp sed Regular Expressions

En av nøklene til å bruke GNU SED lykkes er å vite hvordan du skal bruke sine regulære uttrykk. Hvis du ser over sed-skript uten å vite regulære uttrykk, kan effekten være ganske urovekkende. Ikke bekymre deg – det er ikke så forvirrende som det ser ut. Denne helgen, tilbringe litt tid med GNU sed faste uttrykk og sette noen reell makt inn i tekstbehandling.

I den første opplæringen på GNU sed vi sett på noen av de grunnleggende syntaks og kommandoer mest brukte, og opsjoner . Men vi fikk ikke se over regulære uttrykk i noen detalj, fordi jeg ønsket å tilbringe litt mer tid på dette emnet for å sikre at vi kunne gi regulære uttrykk tiden de fortjener.

Nesten alle utstrakt bruk av sed kommer til å kreve bruk av regulære uttrykk for å matche mønstre av tekst. For eksempel kan du være på utkikk gjennom en fil prøver å matche og erstatte (eller fjerne) HTML-elementer, IP-adresser, telefonnumre eller variabler. Kanskje du prøver å bruke sed til " skrape " en RSS-feed for nyttig informasjon. Uansett hva du prøver å gjøre, du kommer til å støte opp mot regulære uttrykk før eller senere.

En liten advarsel før vi begynner, de regulære uttrykk jeg viser her gjelder GNU sed spesielt . De kan eller ikke kan bære over nøyaktig til andre implementeringer av sed – så hvis du prøver dette på en BSD, Mac OS X, eller bruke noe sånt Busybox, din kjørelengde variere. De fleste
av uttrykkene skal fungere, selvfølgelig, men det er ikke 100% garantert.

Egentlig, la oss gjøre at to
ord om forsiktighet. Når du kjører et vanlig uttrykk du ikke er helt sikker på, gjøre en testkjøring før du gjøre permanente endringer i en fil. Hvis du jobber med filer på disk (i motsetning til en bekk som kommer fra produksjonen av en prosess), kjører uttrykket først bruke -n kommandoen (stille) og bare bruke p å skrive ut de resultater som passer uttrykket snarere enn å redigere filene. Hvis du får de resultatene du forventer,
gjøre endringer. For å komme i gang, vil jeg bruke disse til å illustrere noen av mine eksempler.

begynne på begynnelsen, End på slutten

En ting som kommer godt med er å kunne fortelle sed at du ønsker å matche en streng på begynnelsen eller slutten av en linje. Hvis du er en Vim fan, har du sannsynligvis allerede har en god anelse om hva vi skal bruke her.

For å matche begynnelsen av en linje, bruker ^. For å matche slutten av en linje, bruke $. Her er et eksempel:

sed -n '/^ [a-z] /p' filnavn

Dette forteller sed å matche ethvert linje som begynner med en bokstav. Si at du har en fil som ser slik ut:


 Sedsed1sed 


Hvis du er ny i regulære uttrykk og /eller sed, sannsynligvis ser dette mer forvirrende enn det er, fordi uttrykket følger '/– som ikke er en del av uttrykket i det hele tatt. The 'er der til å begynne uttalelse som vil bli overlevert til sed uten å bli tolket av skallet. Den /forteller sed å søke etter et mønster

Uttrykket vi bruker (^ [a]) sier ". På begynnelsen av linjen, matche ethvert enkelt tegn som er en liten bokstav ".;

Hvis du ønsker å matche noe på slutten av linjen, vil du ønsker å bruke $. Vær oppmerksom på at det må være på slutten av uttrykket
også. Merk at GNU sed vil tillate deg å bruke det på slutten av en " subexpression " hvor du matche flere linjer – men det er ikke nødvendigvis kommer til å jobbe på andre implementeringer av sed.

One, Ingen, Mange

La oss se på matchende ett eller flere tegn, eller ingen. Hvis du ønsker å matche en enkelt forekomst av et tegn eller streng, kan du bruke den bokstavelig. For eksempel " eksempel " vil matche (du gjettet det) eksempel
: men det vil ikke matche Eksempel
. Bruke sed -n '/eksempel /p "vil matche ethvert streng i en fil eller i produksjonen som har som streng i det. Det vil også matche eksempler
eller lenger streng med det bokstavelig sett tegn

Hva om du ønsker å matche null eller flere forekomster av et tegn, bruker * uttrykket slik:.

sed -n '/jeg * sed /p' filnavn

Dette ville matche " sed " eller " tegnes " men ikke " Ibed " eller noe annet som begynner med " I " men ikke fulgt av " sed ".

Hvis du ønsker å matche alle tegn, bruke. – ydmyke dot, som så:

sed -n '/s.d/p' filnavn

Dette ville matche " trist " eller " sed " men ikke " Sad " eller " Sed ".

Vil du matche flere forekomster av alle tegn? Du kombinere. * Tegn. Dette ville matche null eller flere tegn etterfulgt av " red ".

Du kan også matche spesifikke antall tilfeller bruker parentes. Du må gi minst ett nummer, og du kan gi en rekke eller en eksakt tall. Her er hvordan det fungerer:

Hvis du skriver /a \\ {4 \\} /vil matche nøyaktig fire forekomster av tegnet " en " – ikke mer, ikke mindre.

Hvis du bruker /a \\ {2,4 \\} /du vil matche minst to, ikke mer enn fire tilfeller.

Hvis du bruker /a \\ {2 \\} /sier ". kamp minst to og holde det gående

Enkelt, ikke sant? Ja, det ser veldig rotete – i stor grad på grunn av alle skilletegn som er nødvendig.

Lister

La oss snakke om å matche en liste. Det er når du ønsker å matche alle tegn i en liste. La oss si at du vil passe alle tegn fra " A " til " M " men ingenting etter det. (Kanskje du ønsker å finne alle navnene i en fil og sortere dem etter fornavn eller etternavn.) Her er hvordan du ville gjøre det:

sed -n '/^ [AM] /p' filnavn

Det er sed-tale for " kamp A til M på begynnelsen av linjen. " (Husk ^ forteller sed å lete etter begynnelsen av linjen.)

Her vil matche noen navn (eller andre ord) på begynnelsen av linjen som begynner med disse store bokstaver, men ingenting som begynner med en ikke-alfategn eller lavere bekledde brev.

For godt mål, kaste i form på slutten av kommandoen med et rør for å få navnene i alfabetisk rekkefølge.

Hva hvis du bare ønsker å matche noen få tegn, men ikke et område? Deretter kan du bruke noe sånt som dette:

sed -n '/^ [AEIOU] /p' filnavn

På den måten kan du finne alle navnene som begynner med en vokal.

Hvis du ønsker å matche alle navnene som ikke
starter med en vokal, kan du bruke ^ tegnet igjen for å fortelle sed ikke å matche utvalget, som så :

sed -n '/^ [^ AEIOU] /p' filnavn

Merk at dette uttrykket vil ikke bare kamp strenger som starter med store bokstaver som aren ' t i området, men også små bokstaver og tall.

matchende en HTML Tag

La oss se på et siste eksempel. Hva om jeg ønsker å matche en HTML-kode som starter i begynnelsen av en linje, men er ikke en < p > tagge? Jeg vil bruke denne:

sed -n '/^ < [^ p] [^ >] * > /p' file.html

Det vil matche alle tagger på begynnelsen av linjen, med mindre de er en " p " tag.

Practice, øve, øve

Det er egentlig bare én måte å bli flinke til å bruke regulære uttrykk, og det er praksis
. Ta deg tid til denne helgen for å jobbe med sed faste uttrykk og se om du ikke kan bygge litt muskler minnet slik at neste gang du trenger å matche omtrent enhver samling av tegn i en fil eller strøm av tekst.

regulære uttrykk kan bli ganske hårete, men så ubehagelig som de kan virke i begynnelsen, de er vel verdt å lære. GNU sed mestere vil merke jeg ikke har dekket alle
mulig vanlig uttrykk her. Det er fordi jeg ønsker å gi en forsiktig introduksjon, heller enn å prøve å koke havet i en tutorial. Hvis du allerede er kjent med å bruke regulære uttrykk og /eller sed, kan dette virke ganske grunnleggende. Men jeg husker min første introduksjon til regulære uttrykk, og ønsker at andre tutorials (det vil si de som jeg har lært fra) hadde vært litt mindre av kjøkkenbenken variasjon.

Neste uke vil vi bryte opp den sed serien med en titt på noen mer avanserte operasjoner med sed som kombinerer det vi allerede har lært om sed grunnleggende kommandoer og regulære uttrykk, og noen ekstra funksjoner som vi ikke har dekket ennå. Anmeldelser