Hvordan finder jeg filer efter filtype?

Jeg ved, at jeg kan finde filer ved hjælp af find: find . -type f -name "sunrise" . Eksempel på resultat:

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

Jeg ved også, at jeg kan bestemme filtypen for en fil: file sunrise. Eksempel på resultat:

sunrise: PEM RSA private key 

Men hvordan kan jeg finde filer efter filtype?

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

./astronomy/sunrise ./schedule/sunrise 

Kommentarer

  • Der er ingen --filetype mulighed for findkommandoen eller andet, der fortæller dig filtypen. Det eneste, du kan gøre, er at bruge --exec file {} \; og derefter pibe det i grep Bourne, hvis du var på udkig efter bash-scripts eller grep Perl hvis du var på udkig efter Perl-manuskripter eller noget i retning af disse linjer.

Svar

“Filtyper” på et Unix-system er ting som almindelige filer, kataloger, navngivne rør, karakterspecifikke filer, symbolske links osv. Dette er typen af filer, som find kan filtrere videre med dens -type mulighed.

find hjælpeprogram kan ikke i sig selv skelne mellem et “shell-script”, “JPEG-billedfil” eller nogen anden type almindelig fil . Disse typer data kan dog skelnes ved hjælp af file -værktøjet, der ser på bestemte signaturer i selve filerne for at bestemme deres type.

En almindelig måde at mærke på de forskellige typer datafiler er efter deres MIME-type , og file er i stand til at bestemme MIME-typen af en fil.


Brug af file med find til at registrere MIME-typen af almindelige filer og brug den for kun at finde shell-scripts:

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

eller ved hjælp af bash,

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

Tilføj -name sunrise før -exec hvis du kun ønsker at registrere scripts med det navn.

Kommandoen find ovenfor finder alle almindelige filer i eller under den aktuelle mappe, og kald for et kort shell-script til hver sådan fil. Dette script kører file -bi på den fundne fil og afsluttes med nul udgangsstatus, hvis output fra denne kommando indeholder strengen /x-shellscript. Hvis output ikke indeholder den streng, afsluttes den med en exit-status, der ikke er nul, hvilket får find til at fortsætte med det samme med den næste fil. Hvis filen viste sig at være et shell-script, fortsætter kommandoen find til filens stienavn (-print på ende, som også kunne erstattes af en anden handling).

Kommandoen file -bi sender MIME-typen af filen. For et shell-script på Linux ( og de fleste andre systemer), ville dette være noget som

text/x-shellscript; charset=us-ascii 

mens det er på systemer med en lidt ældre variant af file utility, det kan være

application/x-shellscript 

Den fælles bit er /x-shellscript understreng.

Bemærk, at på macOS skal du bruge file -bI i stedet for file -bi på grund af grunde ( -i -indstillingen gør noget helt andet). Outputtet på macOS svarer til et Linux-system.


Vil du udføre en brugerdefineret handling på hvert fundet shell-script kunne du gøre det at med en anden -exec i stedet for -print i find kommandoerne ovenfor, men det ville det også være muligt at gø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 {} + 

Relateret:

Svar

Du kan udføre find på hver fundet fil og grep derefter efter det resultat, du er interesseret 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 gøre søgemønsteret så tæt som muligt på din forventning om at holde antallet af de falske positive matcher lavt.

Pas på, at filer med nye linjer i deres filnavne kan forårsage problemer med denne tilgang.

Svar

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

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *