Teksti otsimine: grep ja sugulased
Loogika
grep on seotud torude, failide ja logidega, sest ta võtab ridu sisse ja valib neist välja need, mis sobivad mustriga.
See tähendab, et grep-i kasutatakse väga tihti koos:
- failidega
- torudega
- logide ja konfiguratsioonidega
Kõige olulisem mõte on: grep ei “tee teksti targemaks”, vaid filtreerib ridu.
Kiirülevaade
Eesmärk on suurest tekstihulgast kiiresti õiged read välja valida. grep on sageli esimene filter, mitte kogu lahendus.
| Käsk või lipp | Milleks | Mida tavaliselt näed |
|---|---|---|
grep muster fail | jäta alles sobivad read | ainult vastega read |
grep -v | jäta alles mittesobivad read | read, kus mustrit ei ole |
grep -r | otsi failipuust | failinimed ja vastega read |
grep -n | lisa reanumbrid | number rea ees |
| vasteid pole | tulemus puudub | tühi väljund |
Tüüpilised algaja vead
- arvatakse, et
grepotsib “sõnu”, kuigi ta töötab ridade kaupa - unustatakse tõstutundlikkus ja imestatakse, miks vasteid ei leita
- aetakse segi lihtne tekst ja regulaaravaldis
Kiirspikker
grep 'muster' fail.txtotsib mustritgrep -nnäitab reanumbreidgrep -ieirab tõstutundlikkustgrep -rotsib rekursiivseltgrep -vpöörab vaste ümber
Kõige sagedasemad valikud alguses:
-nreanumbrid-itõstutundetu otsing-rrekursiivne otsing-vnäita mittevastavaid ridu-Elaiendatud regulaaravaldis-Fotsi fikseeritud sõnet, mitte regexit
Käivita need käsud
printf 'kass\nkoer\nKass\n' > loomad.txt
grep 'kass' loomad.txt
grep -i 'kass' loomad.txt
grep -n 'koer' loomad.txt
grep -r 'TODO' .
grep -v '^#' seadistus.conf
grep, egrep, fgrep
Ajalooliselt:
grepotsib tavalise mustri järgiegreptähistas laiendatud regulaaravaldisifgreptähistas fikseeritud teksti
Tänapäeval kasutatakse sageli:
grep -E 'muster'
grep -F 'sone'
Praktiline reegel:
- kui otsid lihtsalt täpset teksti, siis
grep -F - kui otsid mustrit, siis
grepvõigrep -E
Kiired töökujud
grep 'muster' fail.txtotsib ühest failist sobivad readgrep -n 'muster' fail.txtlisab väljundisse reanumbridgrep -i 'muster' fail.txteirab tõstutundlikkustgrep -r 'muster' .otsib rekursiivselt praegusest kaustastgrep -F 'sõne' fail.txtotsib täpset sõnet ilma regexitagrep -R 'muster' .otsib rekursiivselt ka siis, kui all on alamkaustad
Väga praktiline 1-liner on:
grep -R 'TODO' .
See on sageli üks kiiremaid viise aru saada:
- kus projektis mingi sõna või märksõna esineb
- kas mõni seadistus, URL või funktsiooninimi on üldse olemas
Päris näide: suur sõnaloend ja mustriotsing
Siin on hea näha, kuidas grep on seotud ka teksti puhastamise ja torudega. Mõte ei ole lihtsalt "otsi faili seest", vaid:
- too andmed alla
- tee need ühtlaseks
- otsi huvitavat mustrit
Kui sul on veebis oma andmekaust, on mugav kasutada baas-URL-i:
BASE_URL="https://sinu-domeen/~vilo/linux"
curl -L "$BASE_URL/data/words.txt" -o words.txt
Kui tahad teha samu katseid ilma veebita, sobib hästi ka repo lokaalne fail:
cp data/generated-words.txt words.txt
Kui fail on juba kohalikus kaustas olemas, võid alustada otse sellest.
Järgmine samm on teha sõnad väikesteks tähtedeks ja jätta alles ainult read, mis koosnevad tähtedest või numbritest:
tr '[:upper:]' '[:lower:]' < words.txt | grep -E '^[[:alnum:]]+$' > words-clean.txt
Siin:
tr '[:upper:]' '[:lower:]'teeb sõnad väikesteks tähtedeksgrep -E '^[[:alnum:]]+$'jätab alles ainult need read, kus terve rida koosneb tähtedest või numbritest- tulemus kirjutatakse faili
words-clean.txt
Nüüd saab teha huvitavama otsingu:
grep -x '..a..t..l.' words-clean.txt
Oluline loogika:
-xtähendab, et muster peab katma kogu rea.tähendab "üks suvaline märk"- muster
..a..t..l.otsib 10-märgilisi ridu, kus: - kolmas märk on
a - kuues märk on
t - üheksas märk on
l
Kui vasteid on liiga palju, lisa näiteks:
grep -x '..a..t..l.' words-clean.txt | head
Või loenda vasteid:
grep -x '..a..t..l.' words-clean.txt | wc -l
See on hea näide, sest siin saavad kokku:
curlvõiwget- torud
trgrep -Egrep -x
See on juba päris töövoog, mitte ainult üksik käsunäide.
Päris terminali transkript
Selles näites ei anna esimene otsing vastet. Järgmine käsk teeb sisendi enne väiketäheliseks ja vaste muutub nähtavaks.
kasutaja@mac tmp % wget https://raw.githubusercontent.com/dwyl/english-words/refs/heads/master/words.txt
...
'words.txt' saved
kasutaja@mac tmp % cat words.txt | grep -x 'a..y..l.e'
kasutaja@mac tmp % cat words.txt | tr 'A-Z' 'a-z' | grep -x 'a..y..l.e'
abbyville
kasutaja@mac tmp % cat words.txt | tr 'A-Z' 'a-z' | grep -x 'a.t.l'
antal
aptal
artal
artel
astel
attal
axtel
kasutaja@mac tmp % cat words.txt | tr 'A-Z' 'a-z' | grep -x 'a.t.l' | grep -o .
a
n
t
a
l
a
p
t
a
l
a
r
t
a
l
a
r
t
e
l
a
s
t
e
l
a
t
t
a
l
a
x
t
e
l
kasutaja@mac tmp % cat words.txt | tr 'A-Z' 'a-z' | grep -x 'a.t.l' | grep -o . | sort | uniq -c | sort -nr
11 a
8 t
7 l
3 e
2 r
1 x
1 s
1 p
1 n
Selle töövoo loogika on:
- esimene
grep -x 'a..y..l.e'ei leidnud midagi, sest failis oli vaste suure algustähega tr 'A-Z' 'a-z'muutis sisendi väiketäheliseks- pärast seda leidus vaste
abbyville - muster
a.t.lleidis mitu 5-tähelist sõna grep -o .lõhkus iga vaste üksikuteks märkidekssort | uniq -c | sort -nrnäitas, milliseid tähti nendes vastetes esineb kõige rohkem
Sama töövoog ühendab mitu tuttavat sammu:
grepotsib mustri järgitrmuudab teksti kujusortjauniq -ckoondavad tulemuse statistikaks
Kui eesmärk on ainult mustriotsing, võib toru cat words.txt | ... asemel kirjutada lühemalt:
tr 'A-Z' 'a-z' < words.txt | grep -x 'a..y..l.e'
Pikem kuju sobib siis, kui tahad eraldi näha, kuidas tekst liigub käsust järgmisse.
Edasijõudnule: tagasiviited ja korduv muster
GNU grep toetab ka tagasiviiteid. See tähendab, et saad öelda: "otsi midagi, kus seesama eelnevalt leitud tükk kordub uuesti".
Näide:
kasutaja@mac tmp % cat words.txt | tr 'A-Z' 'a-z' | grep -E '(..)\1\1+'
a.a.a.
aaaaaa
k.k.k.
larararia
logogogue
ratatat
ratatats
ratatat-tat
Selle mustri loogika on:
(..)võtab kaks suvalist märki ja jätab need meelde\1tähendab "sama kahe märgi paar uuesti"- teine
\1+tähendab, et see sama paar kordub veel vähemalt ühe korra
Seega otsitakse ridadest kohta, kus mingi kahe märgi paar kordub vähemalt kolm korda järjestikku.
Näited:
aaaaaasobib, sestaakordub kolm kordaa.a.a.sobib, sesta.kordub kolm kordaratatatsobib, sest reas leidub alammusteratatat, kusatkordub kolm korda
Viimane näide näitab ka -x mõju:
- ilma
-x-ta otsibgrepvastet rea seest -x-ga peab kogu rida mustriga sobima
See tähendab, et:
cat words.txt | tr 'A-Z' 'a-z' | grep -E '(..)\1\1+'
otsib rea seest sobivaid kohti, aga:
cat words.txt | tr 'A-Z' 'a-z' | grep -x -E '(..)\1\1+'
nõuab, et terve rida koosneks sellisest korduvast mustrist.
Tagasiviited sobivad katsetamiseks ja mõneks erijuhtumiks. Igapäevases tekstifiltreerimises eelista võimalusel lihtsamat mustrit, sest tagasiviited võivad olla aeglasemad ja raskemini loetavad.
Minitest
- Loo fail, kus on viis sõna eri ridadel.
- Otsi üht sõna tõstutundlikult ja siis tõstutundetult.
- Otsi rekursiivselt sõna
TODOmõnes projektikaustas. - Võta suuremast sõnaloendist ainult väiketähelised alfanumbrilised read ja otsi neist mustriga
grep -x. - Proovi GNU
grep-iga mustrit( .. )\1\1+ilma tühikuteta ja selgita, miksratatatsobib ilma-x-ta.
Lisalugemine
Selle teema usaldusväärsemad viited leiad lisast Lisa E: usaldusväärsed viited ja lisalugemine.
Peatüki täisspikker
Töövood
Eesmärk
grep valib sisendist välja ainult need read, mis sobivad mustriga; see on filtritööriist, mitte tekstiredaktor
Põhikujud
grep 'kass' loomad.txtotsi ühest failistgrep -i 'kass' loomad.txtotsi tõstutagrep -n 'koer' loomad.txtnäita reanrgrep -r 'TODO' .otsi puustgrep -F 'https://example.com' fail.txtotsi täpset sõnetgrep -v '^#' seadistus.confjäta kommentaarid välja
Olulisemad lipud, märgid ja kiirnupud
-itõstutundetu-nreanumbrid-rrekursiivne-vjäta vasted välja-Ftäpne sõne-Elaiendatud regex