grep & Regex: Mestre Linux-søket med regulære uttrykk

Utforsk kraften i Grep og Regex

Om du har erfaring med Linux, er du sannsynligvis kjent med grep, et kommandolinjeverktøy for tekstsøk. Dette verktøyet er en viktig ressurs for avanserte Linux-brukere. Men bruken av grep alene, uten regulære uttrykk, kan være begrensende.

Hva er egentlig Regex?

Regex, eller regulære uttrykk, er avanserte mønstre som kan forbedre grep sine søkefunksjoner betydelig. De gir deg muligheten til å filtrere resultater mer presist. Med litt øvelse vil du oppdage hvor effektivt regex kan brukes, ikke bare med grep, men også med andre Linux-kommandoer.

I denne veiledningen skal vi dykke ned i hvordan du kan utnytte grep og Regex på best mulig måte.

Forutsetninger

For å kunne bruke grep med Regex, kreves det et solid grunnlag i Linux. Er du nybegynner, anbefaler vi å utforske våre Linux-guider først.

Du trenger også tilgang til en datamaskin med et Linux-operativsystem. Valg av Linux-distribusjon er opp til deg. Om du bruker Windows, kan du benytte Linux via WSL2. Mer informasjon om dette finner du her.

Tilgang til kommandolinjen, eller terminalen, er nødvendig for å utføre kommandoene i denne veiledningen.

I tillegg trenger du en eller flere tekstfiler for å prøve eksemplene. For anledningen genererte jeg en tekstfil ved hjelp av ChatGPT, der jeg ba den om å skrive om teknologi. Jeg brukte følgende spørring:

«Lag en tekst på 400 ord om teknologi. Teksten bør dekke de fleste områder innen teknologi, og gjenta gjerne teknologinavn gjennom teksten.»

Etter å ha generert teksten, kopierte jeg den og lagret den i filen tech.txt. Denne filen vil vi bruke gjennom hele denne veiledningen.

Til slutt er det essensielt å ha en grunnleggende forståelse av grep-kommandoen. Du kan sjekke ut 16 eksempler på grep-kommandoer for å friske opp kunnskapen. Vi vil også kort introdusere grep-kommandoen for å komme i gang.

Syntaks og eksempler på grep-kommando

Syntaksen for grep er enkel:

$ grep -options [regex/pattern] [files]

Kommandoen krever et mønster og en liste over filer å søke i.

grep tilbyr flere alternativer som endrer funksjonaliteten, inkludert:

  • -i: Ignorerer forskjellen mellom store og små bokstaver.
  • -r: Utfører et rekursivt søk i mapper.
  • -w: Søker etter hele ord, ikke delvise.
  • -v: Viser linjer som *ikke* samsvarer med mønsteret.
  • -n: Viser linjenummeret for hvert treff.
  • -l: Viser bare filnavnene som inneholder treff.
  • --color: Fargekoder resultatet.
  • -c: Teller antall linjer som samsvarer med mønsteret.

#1. Søk etter et helt ord

For å søke etter et helt ord, bruk -w-argumentet. Dette vil forhindre at grep returnerer delvise treff.

$ grep -w 'tech\|5G' tech.txt

Dette kommandoeksemplet vil søke etter ordene «5G» og «tech» i hele teksten, og markere dem i rødt.

|-tegnet brukes som en «eller»-operator, og må escapes med en backslash for at grep ikke skal tolke det som et spesialtegn.

#2. Søk uten å skille mellom store og små bokstaver

For å utføre et søk som ikke tar hensyn til store eller små bokstaver, bruk argumentet -i:

$ grep -i 'tech' tech.txt

Denne kommandoen vil finne alle forekomster av «tech», uavhengig av om det er skrevet med store eller små bokstaver, enten som et helt ord eller del av et ord.

#3. Vise linjer som ikke samsvarer

For å vise alle linjer som ikke inneholder et spesifikt mønster, bruk argumentet -v:

$ grep -v 'tech' tech.txt

Outputen viser alle linjer som *ikke* inneholder ordet «tech». Du vil også se tomme linjer, som representerer linjene mellom avsnitt.

#4. Utføre et rekursivt søk

For å søke rekursivt i en mappe, bruk argumentet -r:

$ grep -R 'error\|warning' /var/log/*.log
#output
/var/log/bootstrap.log:2023-01-03 21:40:18 URL:http://ftpmaster.internal/ubuntu/pool/main/libg/libgpg-error/libgpg-erro 0_1.43-3_amd64.deb [69684/69684] -> "/build/chroot//var/cache/apt/archives/partial/libgpg-error0_1.43-3_amd64.deb" [1]
/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 5 package 'dpkg':
/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 5 package 'dpkg':
/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 24 package 'dpkg':
/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 24 package 'dpkg':
/var/log/bootstrap.log:dpkg: warning: ignoring pre-dependency problem!

Dette søker rekursivt etter ordene «error» og «warning» i alle .log-filene i /var/log-mappen. Dette er praktisk for å identifisere feil og advarsler i loggfiler.

Grep og Regex: Hva det er og eksempler

Når du arbeider med regex, er det viktig å vite at det finnes tre hovedsyntakser:

  • Grunnleggende regulære uttrykk (BRE)
  • Utvidede regulære uttrykk (ERE)
  • Perl-kompatible regulære uttrykk (PCRE)

grep bruker BRE som standard. For å bruke ERE eller PCRE, må du spesifisere dette. grep tolker også spesialtegn som vanlige tegn. Hvis du ønsker å bruke spesialtegn som ?, + eller ), må du escape dem med en backslash (\).

Syntaksen for grep med regex er:

$ grep [regex] [filenames]

La oss se noen eksempler:

#1. Eksakte ordsøk

For å utføre et eksakt ordsøk, oppgi det ønskede ordet som et regulært uttrykk. Et enkelt ord er nemlig også et regulært uttrykk.

$ grep "technologies" tech.txt

Du kan også bruke eksakte treff for å finne brukere. For å gjøre dette, kjør:

$ grep bash /etc/passwd
#output
root:x:0:0:root:/root:/bin/bash
nitt:x:1000:1000:,,,:/home/nitt:/bin/bash

Dette viser brukere som har tilgang til bash-skallet.

#2. Anker-matching

Anker-matching er en nyttig teknikk for avanserte søk som benytter spesialtegn. I regulære uttrykk finnes det flere ankertegn for å representere bestemte posisjoner i teksten. Disse inkluderer:

  • ^ (caret): Markerer starten av en streng eller linje og søker etter en tom streng.
  • $ (dollar): Markerer slutten av en streng eller linje og søker etter en tom streng.

Andre ankertegn er \b (ordgrense) og \B (ikke-ordgrense).

  • \b (ordgrense): Angir posisjonen mellom et ord og et ikke-ordtegn, slik at du kan matche hele ord.
  • \B (ikke-ordgrense): Angir en posisjon som ikke er mellom to ord eller to ikke-ordtegn.

La oss se noen eksempler:

$ grep '^From' tech.txt

Caret (^) krever at ordet eller mønsteret samsvarer med starten av linjen og tar hensyn til store og små bokstaver. Hvis du kjører følgende kommando, vil den derfor ikke returnere noe:

$ grep '^from' tech.txt

På samme måte kan du bruke $-symbolet for å finne setninger som slutter med et gitt mønster, streng eller ord:

$ grep 'technology.$' tech.txt

Du kan kombinere både ^ og $-symboler:

$ grep "^From \| technology.$" tech.txt

Denne outputen viser setninger som starter med «From» og setninger som slutter med «technology.»

#3. Gruppering

For å søke etter flere mønstre samtidig, kan du bruke gruppering. Dette lar deg behandle grupper av tegn og mønstre som en enhet. For eksempel kan du lage en gruppe som heter (tech) som inkluderer tegnene «t», «e», «c» og «h».

Her er et eksempel:

$ grep 'technol\(ogy\)\?' tech.txt

Gruppering lar deg matche gjentatte mønstre, fange grupper og søke etter alternativer.

Alternativt søk med gruppering

Her er et eksempel på et alternativt søk:

$ grep "\(tech\|technology\)" tech.txt

For å utføre et søk på en streng med et pipe-symbol, bruk følgende eksempel:

$ echo "tech technological technologies technical" |  grep "\(tech\|technology\)"
#output
"tech technological technologies technical"

Fange grupper, ikke-fangende grupper og gjentatte mønstre

Hva med å fange og ikke-fange grupper?

Du oppretter en gruppe i regex, og sender den til strengen eller en fil for å fange grupper.

$ echo 'tech655 tech655nical technologies655 tech655-oriented 655' | grep "\(tech\)\(655\)"
#output
tech655 tech655nical technologies655 tech655-oriented 655

For ikke-fangende grupper, bruk ?: inne i parentes.

Til slutt, har vi gjentatte mønstre. Du må endre regex for å søke etter gjentatte mønstre:

$ echo 'teach tech ttrial tttechno attest' | grep '\(t\+\)'
#output
'teach tech ttrial tttechno attest'

Dette regulære uttrykket søker etter en eller flere forekomster av tegnet «t».

#4. Tegnklasser

Tegnklasser gjør det enkelt å skrive regex-uttrykk. De bruker firkantparenteser. Noen vanlige tegnklasser inkluderer:

  • [:digit:]: Tall fra 0 til 9.
  • [:alpha:]: Alfabetiske tegn.
  • [:alnum:]: Alfanumeriske tegn.
  • [:lower:]: Små bokstaver.
  • [:upper:]: Store bokstaver.
  • [:xdigit:]: Heksadesimale tall, inkludert 0-9, A-F og a-f.
  • [:blank:]: Tomme tegn som tabulator eller mellomrom.

La oss se noen eksempler:

$ grep [[:digit]] tech.txt

$ grep [[:alpha:]] tech.txt

$ grep [[:xdigit:]] tech.txt

#5. Kvantifikatorer

Kvantifikatorer er metategn som lar deg spesifisere hvor mange ganger et mønster skal forekomme. Her er noen eksempler:

  • *: Null eller flere forekomster.
  • +: En eller flere forekomster.
  • ?: Null eller en forekomst.
  • {x}: Akkurat x forekomster.
  • {x, }: x eller flere forekomster.
  • {x,z}: Mellom x og z forekomster.
  • {, z}: Opptil z forekomster.
$ echo 'teach tech ttrial tttechno attest' | grep -E 't+'
#output
'teach tech ttrial tttechno attest'

Dette eksemplet søker etter en eller flere forekomster av tegnet «t». -E brukes her for å aktivere utvidet regex (som vi vil snakke om nedenfor.)

#6. Utvidet regulært uttrykk

Hvis du ikke ønsker å escape spesialtegn i mønsteret, kan du bruke utvidet regex. Dette aktiveres ved hjelp av -E-flagget.

$ grep -E 'in+ovation' tech.txt

#7. Bruk av PCRE for komplekse søk

PCRE (Perl Compatible Regular Expression) lar deg gjøre mer avanserte søk. For eksempel kan du bruke \d for å representere [0-9].

Du kan for eksempel bruke PCRE til å søke etter e-postadresser:

echo "Contact me at [email protected]" | grep -P "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b"
#output
Contact me at [email protected]

PCRE sikrer at mønsteret blir matchet. På samme måte kan du bruke et PCRE-mønster for å søke etter datomønstre:

$ echo "The Sparkain site launched on 2023-07-29" | grep -P "\b\d{4}-\d{2}-\d{2}\b"
#output
The Sparkain site launched on 2023-07-29

Denne kommandoen finner datoen i formatet ÅÅÅÅ-MM-DD, og kan tilpasses for å matche andre formater.

#8. Alternasjon

For å matche alternative mønstre, bruk escaped pipe-tegn (\|).

$ grep -L 'warning\|error' /var/log/*.log
#output
/var/log/alternatives.log
/var/log/bootstrap.log
/var/log/dpkg.log
/var/log/fontconfig.log
/var/log/ubuntu-advantage.log
/var/log/upgrade-policy-changed.log

Outputen viser filnavn som inneholder «warning» eller «error».

Siste ord

Dette bringer oss til slutten av vår grep og regex-veiledning. Du kan bruke grep med regulære uttrykk for å avgrense søk, og dermed spare tid og automatisere oppgaver. Dette er spesielt nyttig når du skriver skript eller søker i store mengder tekst.

Neste steg kan være å se på ofte stilte Linux-intervjuspørsmål og svar.