Cum se găsesc fișiere după tipul de fișier?

Știu că pot găsi fișiere folosind find: find . -type f -name "sunrise" . Exemplu de rezultat:

./sunrise ./events/sunrise ./astronomy/sunrise ./schedule/sunrise 

Știu, de asemenea, că pot determina tipul de fișier al unui fișier: file sunrise. Exemplu de rezultat:

sunrise: PEM RSA private key 

Dar cum pot găsi fișiere după tipul de fișier?

De exemplu, my-find . -type f -name "sunrise" -filetype=bash-script:

./astronomy/sunrise ./schedule/sunrise 

Comentarii

  • Nu există --filetype opțiune pentru comanda find sau orice altceva care vă va spune tipul de fișier. Singurul lucru pe care îl puteți face este să utilizați --exec file {} \; și apoi să-l introduceți în grep Bourne dacă căutați scripturi bash sau grep Perl dacă căutați scripturi Perl sau ceva asemănător.

Răspundeți

„Tipuri de fișiere” pe un sistem Unix sunt lucruri precum fișiere obișnuite, directoare, țevi numite, fișiere speciale cu caractere, legături simbolice etc. Acestea sunt tipul de fișiere pe care find le poate filtra cu opțiunea -type.

find nu poate distinge prin el însuși între un „script shell”, „fișier imagine JPEG” sau orice alt tip de fișier obișnuit . Cu toate acestea, aceste tipuri de date se pot distinge prin utilitarul file, care analizează semnăturile specifice din fișiere în sine pentru a determina tipul lor.

Un mod comun de etichetare diferitele tipuri de fișiere de date sunt în funcție de tipul MIME și file poate determina tipul MIME al unui fișier.


Folosind file cu find pentru a detecta tipul MIME al fișierelor obișnuite și utilizați acel pentru a găsi numai scripturi shell:

find . -type f -exec sh -c " case $( file -bi "$1" ) in */x-shellscript*) exit 0 esac exit 1" sh {} ";" -print 

sau, folosind bash,

find . -type f \ -exec bash -c "[[ "$( file -bi "$1" )" == */x-shellscript* ]]" bash {} ";" \ -print 

Adăugați -name sunrise înainte de -exec dacă doriți să detectați numai scripturi cu acel nume.

Comanda find de mai sus va găsi toate fișierele obișnuite din sau sub directorul curent și pentru fiecare astfel de fișier apelați un scurt script shell în linie. Acest script rulează file -bi pe fișierul găsit și iese cu o stare de ieșire zero dacă ieșirea acelei comenzi conține șirul /x-shellscript. Dacă ieșirea nu conține acel șir, acesta iese cu o stare de ieșire diferită de zero, ceea ce face ca find să continue imediat cu următorul fișier. Dacă s-a constatat că fișierul este un script shell, comanda find va continua pentru a afișa calea fișierului (-print la end, care ar putea fi înlocuit și cu o altă acțiune).

Comanda file -bi va genera tipul MIME al fișierului. Pentru un script shell pe Linux ( și majoritatea celorlalte sisteme), acesta ar fi ceva de genul

text/x-shellscript; charset=us-ascii 

în timp ce pe sistemele cu o variantă puțin mai veche a file utilitar, poate fi

application/x-shellscript 

Bitul comun este /x-shellscript sub șir.

Rețineți că pe macOS, va trebui să utilizați file -bI în loc de file -bi din motive ( Opțiunea -i face ceva destul de diferit). Ieșirea pe macOS este similară cu cea a unui sistem Linux.


Ați dori să efectuați o acțiune personalizată? pe fiecare script shell găsit, ați putea face acest lucru at cu un alt -exec în locul -print din comenzile find de mai sus, dar ar fi, de asemenea, posibil să faceți

find . -type f -exec sh -c " for pathname do case $( file -bi "$pathname" ) in */x-shellscript*) ;; *) continue esac # some code here that acts on "$pathname" done" sh {} + 

sau, cu bash,

find . -type f -exec bash -c " for pathname do [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue # some code here that acts on "$pathname" done" bash {} + 

Corelat:

Răspuns

Puteți executa find pe fiecare fișier găsit și apoi grep pentru rezultatul care vă „interesează.

# When looking for ASCII Text find . -type -exec file {} \; | grep "ASCII" # or for MS Word Documents find . -type f -exec file {} \; | grep "Microsoft Word" 

Vă sugerez să faceți modelul de căutare cât mai aproape de așteptările dvs. de a păstra numărul de potrivirile fals pozitive sunt scăzute.

Atenție la faptul că fișierele cu linii noi în numele fișierelor lor pot cauza probleme cu această abordare.

Răspuns

Utilizarea modulului perl” s File::LibMagic:

perl -MFile::LibMagic=:easy -MFile::Find -le " find sub { print $File::Find::name if $_ eq "sunrise" and -f and MagicFile$_ eq "PEM RSA private key" }, @ARGV" -- . 

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *