Hvordan finne filer etter filtype?

Jeg vet at jeg kan finne filer ved hjelp av find: find . -type f -name "sunrise" . Eksempel på resultat:

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

Jeg vet også at jeg kan bestemme filtypen til en fil: file sunrise. Eksempel på resultat:

sunrise: PEM RSA private key 

Men hvordan kan jeg finne filer etter filtype?

For eksempel, my-find . -type f -name "sunrise" -filetype=bash-script:

./astronomy/sunrise ./schedule/sunrise 

Kommentarer

  • Det er ingen --filetype alternativet for finn-kommandoen eller noe annet som vil fortelle deg typen fil. Det eneste du kan gjøre er å bruke --exec file {} \; og deretter pipe det inn i grep Bourne hvis du var på utkikk etter bash-skript eller grep Perl hvis du lette etter Perl-skript eller noe i den retning.

Svar

«Filtyper» på et Unix-system er ting som vanlige filer, kataloger, navngitte rør, karakterspesialfiler, symbolske lenker osv. Dette er typen filer som find kan filtrere videre med alternativet -type.

find verktøy kan ikke i seg selv skille mellom et «skallskript», «JPEG-bildefil» eller noen annen type vanlig fil . Disse typer data kan imidlertid skilles ut ved hjelp av file verktøyet, som ser på bestemte signaturer i filene selv for å bestemme typen.

En vanlig måte å merke de forskjellige typene datafiler er av MIME-typen , og file er i stand til å bestemme MIME-typen til fil.


Bruk file med find til å oppdage MIME-typen av vanlige filer, og bruk den for å bare finne skallskripter:

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

eller ved å bruke bash,

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

Legg til -name sunrise før -exec hvis du bare vil oppdage skript med det navnet.

Kommandoen find ovenfor finner alle vanlige filer i eller under gjeldende katalog, og for hver slik fil kaller du et kort, in-line skallskript. Dette skriptet kjører file -bi på den funnet filen og avsluttes med nullutgangsstatus hvis utdataene fra den kommandoen inneholder strengen /x-shellscript. Hvis utdataene ikke inneholder den strengen, kommer den ut med en utgangsstatus som ikke er null, noe som fører til at find fortsetter umiddelbart med neste fil. Hvis filen ble funnet å være et skallskript, vil kommandoen find fortsette med å sende filens stienavn (-print på enden, som også kan erstattes av en annen handling).

Kommandoen file -bi sender MIME-typen til filen. For et skallskript på Linux ( og de fleste andre systemer), ville dette være noe sånt som

text/x-shellscript; charset=us-ascii 

mens det er på systemer med en litt eldre variant av file verktøy, det kan være

application/x-shellscript 

Den vanlige biten er /x-shellscript understreng.

Merk at på macOS må du bruke file -bI i stedet for file -bi på grunn av grunner ( -i alternativet gjør noe ganske annet). Utdataene på macOS ligner på et Linux-system.


Vil du utføre noen tilpassede handlinger på hvert funnet skallskript, kan du gjøre det at med en annen -exec i stedet for -print i find -kommandoene ovenfor, men det ville det også være mulig å gjøre

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 {} + 

eller, med 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 {} + 

Relatert:

Svar

Du kan kjøre find på alle funnet filer og deretter grep for resultatet du er interessert i.

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

Jeg foreslår at du gjør søkemønsteret så nær som mulig din forventning om å beholde antall de falske positive samsvarene er lave.

Vær oppmerksom på at filer med nye linjer i filnavnene kan forårsake problemer med denne tilnærmingen.

Svar

Bruke perl» s File::LibMagic modul:

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" -- . 

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *