Linux komanda grep je alatka za pronalaženje nizova i obrazaca teksta, koja prikazuje linije koje odgovaraju kriterijumima iz jedne ili više datoteka. Takođe, radi u kombinaciji sa izlazom drugih komandi. U ovom tekstu ćemo objasniti kako se koristi.
Priča o nastanku grep komande
Grep komanda je poznata u Linux i Unix svetu iz tri razloga. Prvo, izuzetno je korisna. Drugo, mnogobrojne opcije mogu biti zbunjujuće. Treće, napisana je u jednoj noći da bi rešila konkretan problem. Prva dva razloga su jasna, ali treći zahteva objašnjenje.
Ken Thompson je izdvojio mogućnosti pretrage regularnih izraza iz tekst editora (koji se izgovara „ed“) i kreirao mali program – za sopstvene potrebe – za pretragu tekstualnih datoteka. Njegov šef odeljenja u Bell Labs, Doug McIlroy, kontaktirao je Thompsona i opisao problem sa kojim se suočio jedan od njegovih kolega, Lee McMahon.
McMahon je pokušavao da identifikuje autore Federalističkih spisa putem analize teksta. Trebao mu je alat koji bi mogao da pretražuje fraze i nizove unutar tekstualnih fajlova. Thompson je te večeri proveo oko sat vremena radeći na tome da svoj alat učini opštom alatkom koju bi drugi mogli da koriste i nazvao ga grep. Ime je preuzeo iz komandnog niza ed g/re/p, što znači „globalna pretraga regularnog izraza“.
Možete pogledati video snimak u kojem Thompson govori Brianu Kernighanu o nastanku grep-a.
Osnovne pretrage sa grep-om
Da biste pretražili niz unutar datoteke, unesite termin za pretragu i naziv datoteke u komandnoj liniji:
Prikazane su linije koje odgovaraju. U ovom slučaju, to je jedna linija. Tekst koji odgovara je istaknut. To je zato što u većini distribucija grep ima alias za:
alias grep='grep --colour=auto'
Pogledajmo rezultate kada postoji više linija koje se podudaraju. Tražićemo reč „Prosek“ u datoteci evidencije aplikacije. Pošto se ne sećamo da li je reč napisana malim slovima u datoteci evidencije, koristićemo opciju -i (zanemari velika i mala slova):
grep -i Average geek-1.log
Svaka linija koja odgovara je prikazana, sa istaknutim tekstom u svakoj od njih.
Linije koje se ne podudaraju možemo prikazati pomoću opcije -v (obrnuto podudaranje).
grep -v Mem geek-1.log
Nema isticanja zato što su to linije koje se ne podudaraju.
Možemo da nateramo grep da bude potpuno tih. Rezultat se prosleđuje ljusci kao povratna vrednost iz grep-a. Rezultat nula znači da je string pronađen, a rezultat jedan znači da nije pronađen. Možemo da proverimo povratni kod pomoću $? specijalnih parametara:
grep -q average geek-1.log
echo $?
grep -q wdzwdz geek-1.log
echo $?
Rekurzivne pretrage sa grep-om
Da biste pretraživali ugneždene direktorijume i poddirektorijume, koristite opciju -r (rekurzivna). Imajte na umu da ne navodite ime datoteke u komandnoj liniji, već morate da navedete putanju. Ovde tražimo u trenutnom direktorijumu „.“ i bilo kom poddirektorijumu:
grep -r -i memfree .
Izlaz uključuje direktorijum i ime datoteke svake linije koja odgovara.
Možemo naterati grep da prati simboličke veze koristeći opciju -R (rekurzivna dereferenca). Imamo simboličku vezu u ovom direktorijumu, koja se zove logs-folder. Pokazuje na /home/dave/logs.
ls -l logs-folder
Hajde da ponovimo našu poslednju pretragu sa opcijom -R (rekurzivna dereferenca):
grep -R -i memfree .
Simbolička veza se prati, a direktorijum na koji ukazuje se takođe pretražuje pomoću grep-a.
Pretraga celih reči
Po podrazumevanim podešavanjima, grep će prikazati liniju ako se cilj pretrage pojavi bilo gde u toj liniji, uključujući i unutar drugog niza. Pogledajte ovaj primer. Tražićemo reč „free“.
grep -i free geek-1.log
Rezultati su redovi koji u sebi imaju string „free“, ali to nisu zasebne reči. Oni su deo niza „MemFree“.
Da biste naterali grep da prikazuje samo zasebne „reči“, koristite opciju -w (regex reči).
grep -w -i free geek-1.log
echo $?
Ovog puta nema rezultata jer se termin za pretragu „free“ ne pojavljuje u datoteci kao posebna reč.
Korišćenje više termina za pretragu
Opcija -E (prošireni regex) vam omogućava da tražite više reči. (Opcija -E zamenjuje zastarele egrep verzije grep-a.)
Ova komanda pretražuje dva termina, „prosečno“ i „bez memorije“.
grep -E -w -i "average|memfree" geek-1.log
Sve linije koje odgovaraju su prikazane za svaki od termina za pretragu.
Takođe možete pretraživati više termina koji nisu nužno cele reči, ali mogu biti i cele reči.
Opcija -e (obrasci) vam omogućava da koristite više termina za pretragu u komandnoj liniji. Koristimo funkciju zagrade regularnog izraza da kreiramo obrazac za pretragu. Govori grep-u da odgovara bilo kom od znakova koji se nalaze u zagradama „[].“ To znači da će grep odgovarati ili „kB“ ili „KB“ dok traži.
grep -e "[kK]B" -e "KB" geek-1.log
Oba niza se podudaraju, a u stvari, neke linije sadrže oba niza.
Tačno podudaranje linija
-x (regularni izraz linije) će se podudarati samo sa linijama u kojima se cela linija podudara sa terminom za pretragu. Potražimo oznaku datuma i vremena za koju znamo da se pojavljuje samo jednom u datoteci evidencije:
grep -x "20-Jan--06 15:24:35" geek-1.log
Jedna linija koja se podudara je pronađena i prikazana.
Suprotno od toga je samo prikazivanje linija koje se ne poklapaju. Ovo može biti korisno kada gledate konfiguracione datoteke. Komentari su korisni, ali ponekad je teško uočiti stvarna podešavanja među njima. Evo datoteke /etc/sudoers:
Možemo efikasno da filtriramo linije komentara na ovaj način:
sudo grep -v "https://www.wdzwdz.com/496056/how-to-use-the-grep-command-on-linux/#" /etc/sudoers
Ovo je mnogo lakše za pregled.
Prikazivanje samo teksta koji odgovara
Možda postoji situacija kada ne želite da vidite celu liniju koja odgovara, već samo tekst koji odgovara. Opcija -o (samo podudaranje) radi upravo to.
grep -o MemFree geek-1.log
Ekran je sveden na prikazivanje samo teksta koji odgovara terminu za pretragu, umesto cele linije koja se podudara.
Brojanje sa grep-om
Grep se ne odnosi samo na tekst, već može da pruži i numeričke informacije. Možemo da nateramo grep da broji za nas na različite načine. Ako želimo da znamo koliko puta se termin za pretragu pojavljuje u datoteci, možemo koristiti opciju -c (broj).
grep -c average geek-1.log
Grep izveštava da se termin za pretragu pojavljuje 240 puta u ovoj datoteci.
Možete da naterate grep da prikaže broj linije za svaku liniju koja odgovara koristeći opciju -n (broj reda).
grep -n Jan geek-1.log
Broj linije za svaku liniju koja odgovara je prikazan na početku reda.
Da biste smanjili broj rezultata koji se prikazuju, koristite opciju -m (maksimalni broj). Ograničićemo izlaz na pet linija koje odgovaraju:
grep -m5 -n Jan geek-1.log
Dodavanje konteksta
Često je korisno moći da vidite neke dodatne linije – možda one koje se ne podudaraju – za svaku liniju koja se podudara. Ovo može pomoći da se razlikuje koje od linija koje se podudaraju su one koje vas zanimaju.
Da biste prikazali neke redove posle linije koja se podudara, koristite opciju -A (posle konteksta). Tražimo tri reda u ovom primeru:
grep -A 3 -x "20-Jan-06 15:24:35" geek-1.log
Da biste videli neke redove pre linije koja se podudara, koristite opciju -B (kontekst pre).
grep -B 3 -x "20-Jan-06 15:24:35" geek-1.log
A da biste uključili redove pre i posle reda koji odgovara, koristite opciju -C (kontekst).
grep -C 3 -x "20-Jan-06 15:24:35" geek-1.log
Prikazivanje datoteka koje odgovaraju
Da biste videli imena datoteka koje sadrže termin za pretragu, koristite opciju -l (datoteke sa podudaranjem). Da biste saznali koje datoteke C izvornog koda sadrže reference na datoteku zaglavlja sl.h, koristite ovu komandu:
grep -l "sl.h" *.c
Navedena su imena datoteka, a ne linije koje se podudaraju.
I naravno, možemo tražiti datoteke koje ne sadrže termin za pretragu. Opcija -L (datoteke bez podudaranja) radi upravo to.
grep -L "sl.h" *.c
Početak i kraj linija
Možemo naterati grep da prikazuje samo podudaranja koja su ili na početku ili na kraju reda. Operator regularnog izraza „^“ odgovara početku reda. Praktično sve linije unutar datoteke evidencije će sadržati razmake, ali ćemo tražiti linije koje imaju razmak kao prvi znak:
grep "^ " geek-1.log
Prikazuju se linije koje imaju razmak kao prvi znak – na početku reda.
Da biste podudarali kraj reda, koristite operator regularnog izraza „$“. Potražićemo linije koje se završavaju sa „00“.
grep "00$" geek-1.log
Na ekranu se prikazuju redovi koji imaju „00“ kao poslednje znakove.
Korišćenje cevi sa grep-om
Naravno, možete preneti ulaz u grep, preneti izlaz iz grep u drugi program i imati grep smešten u sredini lanca cevi.
Recimo da želimo da vidimo sva pojavljivanja stringa „ExtractParameters“ u našim datotekama C izvornog koda. Znamo da će ih biti poprilično, tako da ćemo izlaz usmeriti na less:
grep "ExtractParameters" *.c | less
Izlaz je prikazan u less.
Ovo vam omogućava da prelistate listu datoteka i da koristite mogućnosti pretraživanja manje komande.
Ako prebacimo izlaz iz grep u wc i koristimo opciju -l (linije), mi možemo da prebrojimo broj redova u datotekama izvornog koda koje sadrže „ExtractParameters“. (Ovo bismo mogli da postignemo korišćenjem opcije grep -c (count), ali ovo je zgodan način da se demonstrira izvođenje cevi iz grep-a.)
grep "ExtractParameters" *.c | wc -l
Sa sledećom komandom, šaljemo izlaz iz ls u grep i cevovodom izlaz iz grep u sort. Navodimo datoteke u trenutnom direktorijumu, birajući one sa stringom „Aug“ u njima, i sortiranje po veličini datoteke:
ls -l | grep "Aug" | sort +4n
Hajde da to razložimo:
ls -l: Izvršite dugačku listu formata datoteka koristeći ls.
grep „Aug“: Izaberite linije sa ls liste koje imaju „Aug“ u sebi. Imajte na umu da će ovo takođe pronaći datoteke koje imaju „Aug“ u svojim imenima.
sort +4n: Sortiraj izlaz iz grep na četvrtoj koloni (veličina datoteke).
Dobijamo sortiranu listu svih fajlova izmenjenih u avgustu (bez obzira na godinu), u rastućem redosledu veličine datoteke.
Grep: Mala komanda, veliki saveznik
Grep je odličan alat koji vam je na raspolaganju. Datira iz 1974. godine i još uvek je moćan jer nam treba ono što radi, a ništa ne može bolje od njega.
Kombinovanje grep-a sa nekim regularnim izrazima zaista ga podiže na viši nivo.