Linux grep-kommandoen er et streng- og mønstermatchningsværktøj, der viser matchende linjer fra flere filer. Det fungerer også med piped output fra andre kommandoer. Vi viser dig hvordan.
Indholdsfortegnelse
Historien bag grep
grep-kommandoen er berømt i Linux og Unix cirkler af tre grunde. For det første er det enormt nyttigt. For det andet et væld af muligheder kan være overvældende. For det tredje blev den skrevet over natten for at tilfredsstille et bestemt behov. De to første er knald på; den tredje er lidt off.
Ken Thompson havde udtrukket de regulære udtryks søgefunktioner fra ed-editoren (udtales ee-dee) og skabte et lille program – til eget brug – til at søge gennem tekstfiler. Hans afdelingsleder kl Bell Labs, Doug Mcilroy, henvendte sig til Thompson og beskrev problemet en af hans kolleger, Lee McMahon, stod overfor.
McMahon forsøgte at identificere forfatterne til Føderalistiske papirer gennem tekstanalyse. Han havde brug for et værktøj, der kunne søge efter sætninger og strenge i tekstfiler. Thompson brugte omkring en time den aften på at gøre sit værktøj til et generelt værktøj, der kunne bruges af andre og omdøbte det til grep. Han tog navnet fra ed-kommandostrengen g/re/p , som oversættes som “global regulært udtrykssøgning.”
Du kan se Thompson tale til Brian Kernighan om greps fødsel.
Simple søgninger med grep
For at søge efter en streng i en fil skal du sende søgeordet og filnavnet på kommandolinjen:
Matchende linjer vises. I dette tilfælde er det en enkelt linje. Den matchende tekst er fremhævet. Dette skyldes, at grep på de fleste distributioner er aliaseret til:
alias grep='grep --colour=auto'
Lad os se på resultater, hvor der er flere linjer, der matcher. Vi leder efter ordet “Gennemsnit” i en programlogfil. Fordi vi ikke kan huske, om ordet er med små bogstaver i logfilen, bruger vi muligheden -i (ignorer store og små bogstaver):
grep -i Average geek-1.log
Hver matchende linje vises, med den matchende tekst fremhævet i hver enkelt.
Vi kan vise de ikke-matchende linjer ved at bruge muligheden -v (invert match).
grep -v Mem geek-1.log
Der er ingen fremhævning, fordi disse er de ikke-matchende linjer.
Vi kan få grep til at være helt stille. Resultatet sendes til skallen som en returværdi fra grep. Et resultat på nul betyder, at strengen blev fundet, og et resultat af et betyder, at den ikke blev fundet. Vi kan tjekke returkoden ved hjælp af $? særlige parametre:
grep -q average geek-1.log
echo $?
grep -q wdzwdz geek-1.log
echo $?
Rekursive søgninger med grep
Brug indstillingen -r (rekursiv) for at søge gennem indlejrede mapper og undermapper. Bemærk, at du ikke angiver et filnavn på kommandolinjen, du skal angive en sti. Her søger vi i den aktuelle mappe “.” og eventuelle undermapper:
grep -r -i memfree .
Outputtet inkluderer mappen og filnavnet for hver matchende linje.
Vi kan få grep til at følge symbolske links ved at bruge muligheden -R (rekursiv dereference). Vi har et symbolsk link i denne mappe, kaldet logs-folder. Det peger på /home/dave/logs.
ls -l logs-folder
Lad os gentage vores sidste søgning med muligheden -R (rekursiv dereference):
grep -R -i memfree .
Det symbolske link følges, og den mappe, det peger på, søges også af grep.
Søger efter hele ord
Som standard vil grep matche en linje, hvis søgemålet vises hvor som helst på den linje, inklusive inde i en anden streng. Se på dette eksempel. Vi vil søge efter ordet “gratis”.
grep -i free geek-1.log
Resultaterne er linjer, der har strengen “fri” i sig, men de er ikke separate ord. De er en del af strengen “MemFree.”
For at tvinge grep til kun at matche separate “ord”, skal du bruge -w (ord regexp) mulighed.
grep -w -i free geek-1.log
echo $?
Denne gang er der ingen resultater, fordi søgeordet “gratis” ikke vises i filen som et separat ord.
Brug af flere søgetermer
Indstillingen -E (udvidet regexp) giver dig mulighed for at søge efter flere ord. (Muligheden -E erstatter det forældede egrep version af grep.)
Denne kommando søger efter to søgeord, “gennemsnitlig” og “memfri”.
grep -E -w -i "average|memfree" geek-1.log
Alle de matchende linjer vises for hvert af søgetermerne.
Du kan også søge efter flere udtryk, der ikke nødvendigvis er hele ord, men de kan også være hele ord.
Indstillingen -e (mønstre) giver dig mulighed for at bruge flere søgetermer på kommandolinjen. Vi gør brug af funktionen til regulære udtryksparenteser til at skabe et søgemønster. Det fortæller grep at matche et hvilket som helst af tegnene indeholdt i parentes “[].” Dette betyder, at grep vil matche enten “kB” eller “KB”, mens den søger.
Begge strenge er matchede, og faktisk indeholder nogle linjer begge strenge.
Matchende linjer nøjagtigt
-x (line regexp) vil kun matche linjer, hvor hele linjen matcher søgeordet. Lad os søge efter et dato- og tidsstempel, som vi ved kun vises én gang i logfilen:
grep -x "20-Jan--06 15:24:35" geek-1.log
Den enkelte linje, der matcher, findes og vises.
Det modsatte af det er kun at vise de linjer, der ikke stemmer overens. Dette kan være nyttigt, når du ser på konfigurationsfiler. Kommentarer er gode, men nogle gange er det svært at få øje på de faktiske indstillinger blandt dem alle. Her er filen /etc/sudoers:
Vi kan effektivt bortfiltrere kommentarlinjerne sådan her:
sudo grep -v "https://www.wdzwdz.com/496056/how-to-use-the-grep-command-on-linux/#" /etc/sudoers
Det er meget nemmere at parse.
Viser kun matchende tekst
Der kan være en lejlighed, hvor du ikke ønsker at se hele den matchende linje, kun den matchende tekst. Valgmuligheden -o (kun matchende) gør netop det.
grep -o MemFree geek-1.log
Visningen er reduceret til kun at vise den tekst, der matcher søgeordet, i stedet for hele den matchende linje.
Tæller med grep
grep handler ikke kun om tekst, det kan også give numeriske oplysninger. Vi kan få grep til at tælle for os på forskellige måder. Hvis vi vil vide, hvor mange gange et søgeord forekommer i en fil, kan vi bruge -c (tælle) muligheden.
grep -c average geek-1.log
grep rapporterer, at søgeordet forekommer 240 gange i denne fil.
Du kan få grep til at vise linjenummeret for hver matchende linje ved at bruge -n (linjenummer).
grep -n Jan geek-1.log
Linjenummeret for hver matchende linje vises i starten af linjen.
For at reducere antallet af resultater, der vises, skal du bruge indstillingen -m (maks. antal). Vi vil begrænse outputtet til fem matchende linjer:
grep -m5 -n Jan geek-1.log
Tilføjelse af kontekst
Det er ofte nyttigt at kunne se nogle ekstra linjer – muligvis ikke-matchende linjer – for hver matchende linje. det kan hjælpe med at skelne, hvilke af de matchede linjer, der er dem, du er interesseret i.
For at vise nogle linjer efter den matchende linje, brug muligheden -A (efter kontekst). Vi beder om tre linjer i dette eksempel:
grep -A 3 -x "20-Jan-06 15:24:35" geek-1.log
For at se nogle linjer fra før den matchende linje, brug muligheden -B (kontekst før).
grep -B 3 -x "20-Jan-06 15:24:35" geek-1.log
Og for at inkludere linjer fra før og efter den matchende linje, brug -C (kontekst) mulighed.
grep -C 3 -x "20-Jan-06 15:24:35" geek-1.log
Viser matchende filer
For at se navnene på de filer, der indeholder søgetermen, skal du bruge indstillingen -l (filer med match). For at finde ud af, hvilke C-kildekodefiler der indeholder referencer til sl.h-headerfilen, skal du bruge denne kommando:
grep -l "sl.h" *.c
Filnavnene er angivet, ikke de matchende linjer.
Og selvfølgelig kan vi kigge efter filer, der ikke indeholder søgeordet. Indstillingen -L (filer uden match) gør netop det.
grep -L "sl.h" *.c
Start og slutning af linjer
Vi kan tvinge grep til kun at vise match, der enten er i starten eller slutningen af en linje. Operatoren “^” regulære udtryk matcher starten af en linje. Praktisk talt alle linjer i logfilen vil indeholde mellemrum, men vi skal søge efter linjer, der har et mellemrum som deres første tegn:
grep "^ " geek-1.log
De linjer, der har et mellemrum som det første tegn – i starten af linjen – vises.
For at matche slutningen af linjen skal du bruge “$” regulære udtryksoperator. Vi vil søge efter linjer, der ender med “00”.
grep "00$" geek-1.log
Displayet viser de linjer, der har “00” som deres sidste tegn.
Brug af Pipes med grep
Selvfølgelig kan du overføre input til grep , overføre output fra grep til et andet program og have grep placeret i midten af en rørkæde.
Lad os sige, at vi ønsker at se alle forekomster af strengen “ExtractParameters” i vores C-kildekodefiler. Vi ved, at der vil være en del, så vi overfører outputtet til færre:
grep "ExtractParameters" *.c | less
Outputtet præsenteres i mindre.
Dette lader dig bladre gennem fillisten og bruge less’s søgefunktion.
Hvis vi overfører outputtet fra grep til wc og bruger -l (linjer), vil vi kan tælle antallet af linjer i kildekodefilerne, der indeholder “ExtractParameters”. (Vi kunne opnå dette ved at bruge grep -c (tælle), men dette er en smart måde at demonstrere piping ud af grep.)
grep "ExtractParameters" *.c | wc -l
Med den næste kommando overfører vi outputtet fra ls til grep og overfører outputtet fra grep til sort . Vi lister filerne i den aktuelle mappe, og vælger dem med strengen “Aug” i dem, og sortere dem efter filstørrelse:
ls -l | grep "Aug" | sort +4n
Lad os opdele det:
ls -l: Udfør en lang formatliste over filerne ved hjælp af ls.
grep “Aug”: Vælg linjerne fra ls-listen, der har “Aug” i dem. Bemærk, at dette også vil finde filer, der har “Aug” i deres navne.
sort +4n: Sorter outputtet fra grep i den fjerde kolonne (filstørrelse).
Vi får en sorteret liste over alle de filer, der er ændret i august (uanset år), i stigende rækkefølge efter filstørrelse.
grep: Mindre en kommando, mere af en allieret
grep er et fantastisk værktøj at have til din rådighed. Det stammer fra 1974 og er stadig i gang, fordi vi har brug for det, det gør, og intet gør det bedre.
Kobling af grep med nogle regulære udtryk-fu tager det virkelig til næste niveau.