find on pika ajalooga UNIX® utiliit. Selle funktsioon on uurida rekursiivselt läbi üks või rohkem kataloogi ning leida sealt failid, mis vastavad teatud kriteeriumidele. Kuigi see on väga kasulik käsk, on selle süntaks mõnevõrra keeruline ja nõuab harjutamist. Üldiselt näeb süntaks välja selline:
find [võtmed] [kataloogid] [kriteerium1] ... [kriteeriumN] [toiming]
Kui kataloogi ei anta, otsib find läbi aktiivse kataloogi. Kui kriteerium andmata jätta, arvestatakse vaikimisi kriteeriumiks “tõene”, mis tähendab, et leitakse üles kõik failid. Võtmeid, kriteeriume ja toiminguid on nii palju, et siinkohal on võimalik neist ainult mõnel peatuda. Kõigepealt mõned võtmed:
-xdev
: otsingut ei sooritata muude failisüsteemide kataloogides.
-mindepth <n>
: enne failide otsimist liigutakse vähemalt n
taset määratud kataloogist allapoole.
-maxdepth <n>
: otsitakse faile, mis asuvad määratud kataloogist maksimaalselt n
taset allpool asuvates kataloogides.
-follow
: kui nimeviidad osutavad kataloogidele, järgitakse neid. Vaikimisi find viitu ei järgi.
-daystart
: ajaga seotud testide korral (vt. allpool) arvestatakse ajatemplina käesoleva päeva algust, mitte vaikeväärtust (24 tundi enne käesolevat hetke).
Kriteeriumiks võib olla üks või mitu atomaarset testi. Mõned kasulikumad testid:
-type <failitüüp>
: antud tüübiga faili otsimine. failitüüp
võib olla: f
(tavaline fail), d
(kataloog), l
(nimeviit), s
(sokkel), b
(plokkseadmefail), c
(sümbolseadmefail) või p
(toru).
-name <muster>
: antud mustrile vastava nimega failide otsimine. Selle võtme puhul koheldakse mustrit metamärgina (vt. Sektsioon 3, “Metamärkide kasutamine shellis”).
-iname <muster>
: nagu -name
, aga ei arvesta tõstu ehk tähesuurust.
-atime <n>
, -amin <n>
: failide otsimine, mida on viimati kasutatud n
päeva eest (-atime
) või n
minuti eest (-amin
. Samuti võib anda <+n>
või <-n>
, mille korral otsitakse faile, mida on kasutatud vastavalt kas hiljem või varem kui n
päeva/minuti eest.
-anewer <fail>
: failide otsimine, mida on kasutatud hiljem kui faili fail
.
-ctime <n>
, -cmin <n>
, -cnewer <fail>
: sama, mis -atime
, -amin
ja -anewer
, kuid otsitakse faile, mille sisu on vastavatel aegadel muudetud.
-regex <muster>
: sama, mis -name
, kuid muster
tähendab antud juhul regulaaravaldist.
-iregex <muster>
: sama, mis -regex
, aga tõst jäetakse arvestamata.
Teste on veel päris palju, neist annab ülevaate manuaalilehekülg find(1). Testide kombineerimiseks võib kasutada üht järgnevatest võimalustest:
<k1> -a <k2>
: tõene, kui nii k1
kui ka k2
on tõesed; -a
on tegelikult vaikimisi eeldatav, mistõttu võib ka kirjutada lihtsalt <k1> <k2> <k3>
, kui soovite, et sobiksid kõik testid, nii k1
, k2
kui ka k3
.
<k1> -o <k2>
: tõene, kui tõene on kas k1
või k2
või mõlemad. Arvestage, et võtmel -o
seisab tehtejärjestuses madalamal kui -a
, seepärast tuleb näiteks juhul, kui soovite leida faile, mis sobiksid kriteeriumile k1
või k2
ja ka kriteeriumile k3
, kasutada sulge ning kirjutada see kujul ( <k1> -o <k2> ) -a <k3>
. Teil tuleb ühtlasi sulud varjestada (mitteaktiivseks muuta), sest muidu üritab shell
neid oma reeglite järgi tõlgendada!
-not <k1>
: test k1
tagurpidi, mis tähendab, et -not <k1>
on tõene juhul, kui k1
on väär.
Lõpuks saab määrata ka toimingu, mida leitud faili(de)ga ette võtta. Sagedasemad toimingud on järgmised:
-print
: kõigi failide nime näidatakse standardväljundis. See on vaiketoiming.
-ls
: standardväljundis näidatakse iga leitud faili kohta seda, mida näitaks käsk ls -ilds.
-exec <käsurida>
: käivitab kõigi leitud failide puhul käsu käsurida
. Käsurida käsurida
peab lõppema märgiga ;
, mis tuleb varjestada, et shell seda omapäi tõlgendama ei asuks. Faili asukohta märgib {}
. Vt. kasutamisnäiteid.
-ok <käsk>
: sama, mis -exec
, aga pärib iga käsu korral kinnitust.
Ilmselt parim viis kõiki võtmeid ja parameetreid tundma õppida on näidete varal. Oletame, et soovime leida kõik kataloogid kataloogis /usr/share
. Selleks tuleb anda käsk:
find /usr/share -type d
Oletame, et Teil on HTTP-server. Kõik Teie HTML-failid asuvad kataloogis /var/www/html
, kus Te ka parasjagu viibite. Te soovite leida kõik failid, mille sisu pole muudetud kuu aja jooksul. Kuna Teil on mitmeid kirjutamisõigusega kasutajaid, kannavad osad failid laiendit html
, osad aga htm
. Te soovite linkida leitud failid kataloogi /var/www/obsolete
. Selleks tuleb Teil anda käsk[27]:
find \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 \ -exec ln {} /var/www/obsolete \;
See on suhteliselt keeruline näide, mis vajab ilmselt seletust. Kriteerium on järgmine:
\( -name "*.htm" -o -name "*.html" \) -a -ctime -30
ja teeb just seda, mis vaja: leiab kõik failid, mille nime lõpus seisab kas .htm
või .html
(“\( -name "*.htm" -o -name "*.html" \)
”), ja (-a
) mida ei ole muudetud viimase 30 päeva jooksul, mis ongi enam-vähem kuu aega (-ctime -30
). Pange tähele sulge: need on siin vajalikud, sest -a
seisab tehtejärjestuses kõrgemal. Kui neid ei oleks, leitkas kõik failid, mille lõpus seisab .htm
, ning lisaks kõik failid, mille lõpus seisab .html
ja mida ei ole muudetud viimase kuu aja jooksul, mis aga ei vastaks kuidagi meie soovile. Pange tähele ka seda, et sulud on shelli eest varjestatud: kui kirjutada \( ... \)
asemel ( ... )
, hakkaks shell neid oma reeglite järgi tõlgendama ning üritaks käivitada alamshellis -name "*.htm" -o -name "*.html"
... Teine võimalus oleks panna sulud topelt- või ühekordsete jutumärkide vahele, aga längkriips on soovitatavam, sest sel juhul saab läbi ajada ainult ühe märgiga.
Lõpuks on siin ka käsk, mida rakendatakse kõigile failidele:
-exec ln {} /var/www/obsolete \;
Ka siin tuleb märk ;
shell
'i eest varjestada. Vastasel juhul tõlgendaks shell seda käsueraldajana. Kui Teil peaks see meelest minema, hoiatab find teid, et -exec
on argumendita.
Viimane näide: Teil on tohutu kataloog (/shared/pildid
), kus leidub kõikvõimalikke pilte. Te kasutate regulaarselt käsku touch kataloogis leiduva faili tempel
aja uuendamiseks, nii et Teil on olemas aeg, millele toetuda. Te soovite nüüd leida kõik JPEG-pildid, mis on uuemad kui fail tempel
, aga kuna Te olete hankinud pilte erinevatest allikatest, on neil laienditeks nii jpg
, jpeg
kui ka JPG
ja JPEG
. Samuti soovite jätta otsingul kõrvale kataloogi vanad
. Lisaks soovite, et failinimekiri saadetakse Teile e-kirjana (ning Teie kasutajanimi on peter
):
find /shared/pildid -cnewer \ /shared/pildid/tempel \ -a -iregex ".*\.jpe?g" \ -a -not -regex ".*/vanad/.*" \ | mail peter -s "Uued pildid"
Selline käsk on mõistagi tülikas, kui Te peate iga kord kogu joru käsitsi kirja panema - ja Teil läheb seda sageli vaja. Sellise probleemi lihtsaks lahenduseks on lasta käsul perioodiliselt tööle hakata cron-deemoni abil, millest tuleb juttu järgmises osas.
[27] Arvestage, et toodud näite korral on vajalik, et /var/www
ja /var/www/obsolete
asuksid samas failisüsteemis!