Unixcyclopedia - find
August 30th, 2007 Alex
find este una dintre cele mai utile comenzi valabile din linia de comandă, fiind unul din cele mai bune argumente împotriva folosirii managerelor de fişiere grafice (gen Windows Explorer). Cu un File Explorer grafic nu poţi spune într-un mod eficient “caută-mi toate imaginile ce au fost modificate de utilizatorul alex săptămâna trecută, fă arhivă cu ele, şi trimite-le pe mail lui gigi@gmail.com”. Combinată cu “xargs”, plus alte utilitare ce operează pe fişiere, astfel de operaţii devin de 10 ori mai uşoare şi mai uşor de automatizat.
Descriere pe scurt: caută fişiere ce corespund criteriilor date.
Problema 1: efectuează o căutare recursivă în directorul curent după numele fişierului (cu wildcards)
find . -name "*.jpg"
Rezultatul este ceva de genul …
...
./Fotografii/Vacanțe/La Mare (2007)/dsc00956.jpg
./Fotografii/Vacanțe/La Mare (2007)/dsc00957.jpg
./Fotografii/Vacanțe/La Mare (2007)/dsc00958.jpg
./Fotografii/Vacanțe/La Mare (2007)/dsc00959.jpg
...
Directorul unde se face căutarea este cel curent, denotat cu “.”, dar se poate specifica un alt director.
Problema 2: caută toate fişierele ce aparţin de un anumit utilizator.
find . -user alex
Iar rezultatul este iarăşi ceva de genul …
...
./Audio/ToConvert/Diverse/05-senses-ube.ogg
./Audio/ToConvert/Diverse/06-empathy-ube.ogg
./Audio/ToConvert/Diverse/07-reality-ube.ogg
./Audio/ToConvert/Diverse/08-sanity-ube.ogg
./Audio/ToConvert/Diverse/09-identity-ube.ogg
...
Problema 3: caută fişierele de un anumit tip
Un director este tot un fişier. Deasemenea, sub Linux/Unix, pe lângă fişierele fizice de pe hard-disk mai există şi alte tipuri de fişiere (sub Unix filozofia este … aproape orice resursă poate fi tratată ca un fişier).
Tipurile de fişiere disponibile, aşa cum apar la listing-ul comenzii “ls”, sunt …
- - fişier normal
d - director
l - link
c - fişier special (în general se găsesc în /dev)
s - socket
p - named pipe
Pentru a căuta doar anumite tipuri de fişiere (cum ar fi directoarele) cu find, putem utiliza ceva de genul:
find ~/Media/Fotografii/ -type d
Iar rezultatul …
...
/home/alex/Media/Fotografii/Evenimente/Pasti (2007)
/home/alex/Media/Fotografii/Evenimente/Nuntă Ștefan & Veronica
/home/alex/Media/Fotografii/Evenimente/Moț Ioana
/home/alex/Media/Fotografii/Evenimente/Revelion 2006
...
Problema 4: caută fişierele ce depăşesc o anumită dimensiune:
find ~/Media/Audio -size +10M
Problema 5: combinarea şi negarea condiţiilor … caută toate fişierele din directorul cu fişiere audio ce depăşesc 1 MB şi nu sunt mp3-uri
Argumentele pot fi combinate pentru alcătuirea unor criterii de selecţie mai specializate. Deasemenea condiţiile incluse pot fi negate dacă punem în faţa condiţiei semnul exclamării.
find ~/Media/Audio -size +10M ! -name *.mp3
Autopsii
Cu find poţi examina ce fişiere au fost modificate în ultimele 3 zile, sau în ultimele 30 de minute de exemplu. Poţi căuta fişiere cu un anumit set de permisiuni. Poţi deasemenea căuta fişiere ce *nu* aparţin de vreun utilizator sau grup.
Cu astfel de căutări poţi face diagnostice în cazul în care ceva nu merge bine (de exemplu în cazul în care sistemul a fost crăcuit, God forbid).
Aşadar şi prin urmare …
Problema 6: cum pot căuta fişierele ce au modificate/accesate în ultimele X zile ?
Opţiunile disponibile sunt următoarele:
-atime: când au fost fişierele ultima oară accesate
-ctime: când au fost permisiunile fişierelor ultima oară schimbate
-mtime: când au fost fişierele ultima oara schimbate
Parametrul [număr întreg] ce apare lângă aceste opţiuni specifică numărul maxim de zile de la ultima schimbare.
Astfel, pentru a afla fişierele ce au fost schimbate în ultimele 24 de ore:
find /etc -user root -mtime 1
Se pot specifica şi minute în loc de zile, folosind următorul set de instrucţiuni:
-amin: în loc de atime
-cmin: în loc de ctime
-mmin: în loc de mtime
Astfel, pentru a afla fişierele ce au fost schimbate în ultimele 30 de minute:
find /etc -user root -mmin 30
Pentru a afla fişierele ce au fost accesate în ultimele 5 minute:
find /etc -user root -amin 5
Problema 7: cum pot afla toate fişierele cu permisiuni complete de accesare?
find ~ -perm 777
Alte opţiuni utile
-nouser: arată fişierele care nu sunt asociate cu un user
-nogroup: arată fişierele care nu sunt asociate cu un grup
-links n: fişierul are N link-uri
-newer file: se găsesc fişierele modificate mai recent decât fişierul “file”
Combinarea comenzii cu xargs
Este foarte util să combini comanda find cu alte comenzi din consolă pentru a putea executa operaţii complexe pe fişiere. E util de exemplu să iei toate imaginile ce aparţin lui Alex şi au fost modificate azi şi să le muţi într-un director de backup.
Comanda find mai suportă şi opţiunea “-exec” pentru rularea unei comenzi pentru fiecare nume de fişier găsit. Însă eu prefer să mă leg de comanda xargs deoarece combinaţia este mai rapida (-exec rulează o instanţă separată a programului declarat pentru fiecare fişier găsit, şi performanţa e mult mai mică pentru un număr mare de fişiere găsite).
Despre xargs: comanda combină parametrul dat cu liniile venite din stdin şi execută comanda astfel creată.
De exemplu “echo "newDirectory" | xargs mkdir” este echivalent cu “mkdir newDirectory“.
Apare însă o problemă: numele de fişiere pot conţine newlines, iar separarea din output a fişierelor din toate exemple de până acum s-a făcut cu newline (fiecare fişier fiind tipărit pe o linie nouă). Pentru a evita astfel de erori la combinarea cu comanda “xargs” se foloseşte parametrul “-print0″ ce pune caractere NULL ca despărţitor în loc de newline … iar la comanda xargs se foloseşte parametrul “-0″ pentru a indica folosirea caracterelor NULL în stdin. Vezi exemplul următor.
Problema 8: cum pot muta toate imaginile JPG (în afară de cele ce au fost făcute “la mare”) într-un director de backup ?
find ~/Media -name *.jpg ! -iwholename *mare* -print0 | xargs -0 mv --target-directory ~/Backup
În încheiere
Desigur, comanda find este chiar complexă şi mai are parametrii posibili de care n-am discutat, deşi i-am acoperit pe cei mai importanţi. Ca de obicei, de câte ori uiţi un parametru sau vrei sa afli mai multe …
man find
Posted in shell, unix, unixcyclopedia | 4 Comments »