Hoe vind ik bestanden op bestandstype?

Ik weet dat ik bestanden kan vinden met find: find . -type f -name "sunrise" . Voorbeeldresultaat:

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

Ik weet ook dat ik het bestandstype van een bestand kan bepalen: file sunrise. Voorbeeldresultaat:

sunrise: PEM RSA private key 

Maar hoe kan ik bestanden vinden op bestandstype?

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

./astronomy/sunrise ./schedule/sunrise 

Reacties

  • Er is geen --filetype optie voor het find commando of iets anders dat je het type bestand zal vertellen. Het enige dat u kunt doen is --exec file {} \; gebruiken en het vervolgens naar grep Bourne leiden als u op zoek was naar bash-scripts of grep Perl als u op zoek was naar Perl-scripts of zoiets.

Antwoord

“Bestandstypen” op een Unix-systeem zijn zaken als gewone bestanden, mappen, named pipes, karakterspecifieke bestanden, symbolische koppelingen enz. Dit zijn de typen bestanden waarop find kan filteren met de -type optie.

De find kan op zichzelf geen onderscheid maken tussen een “shellscript”, “JPEG-afbeeldingsbestand” of elk ander type gewoon bestand . Deze soorten gegevens kunnen echter worden onderscheiden door het file -hulpprogramma, dat naar bepaalde handtekeningen in de bestanden zelf kijkt om hun type te bepalen.

Een gebruikelijke manier om te labelen de verschillende typen gegevensbestanden zijn door hun MIME-type , en file kan het MIME-type van een bestand.


Gebruik file met find om het MIME-type van gewone bestanden te detecteren, en gebruik dat om alleen shellscripts te vinden:

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

of gebruik bash,

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

Voeg -name sunrise toe voor de -exec als u alleen scripts met die naam wilt detecteren.

Het find commando hierboven zal alle reguliere bestanden in of onder de huidige directory vinden, en voor elk dergelijk bestand een kort in-line shellscript aanroepen. Dit script voert file -bi uit op het gevonden bestand en wordt afgesloten met een nulstatus als de uitvoer van dat commando de tekenreeks /x-shellscript bevat. Als de uitvoer die string niet bevat, wordt deze afgesloten met een exitstatus die niet nul is, waardoor find onmiddellijk doorgaat met het volgende bestand. Als blijkt dat het bestand een shellscript is, gaat het find -commando verder met het uitvoeren van de padnaam van het bestand (de -print aan de end, die ook vervangen zou kunnen worden door een andere actie).

Het file -bi commando zal het MIME-type van het bestand uitvoeren. Voor een shellscript op Linux ( en de meeste andere systemen), zou dit zoiets zijn als

text/x-shellscript; charset=us-ascii 

op systemen met een iets oudere variant van de file hulpprogramma, het kan zijn

application/x-shellscript 

Het algemene bit is de /x-shellscript substring.

Merk op dat u op macOS file -bI zou moeten gebruiken in plaats van file -bi vanwege redenen (de -i optie doet iets heel anders). De uitvoer op macOS is vergelijkbaar met die van een Linux-systeem.


Zou je een aangepaste actie willen uitvoeren op elk gevonden shellscript zou je dat kunnen doen at met een andere -exec in plaats van de -print in de find -opdrachten hierboven, maar zou ook mogelijk zijn om te doen

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

of, met 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 {} + 

Gerelateerd:

Antwoord

Je zou find kunnen uitvoeren op elk gevonden bestand en dan grep voor het resultaat waarin u “geïnteresseerd bent.

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

Ik stel voor om het zoekpatroon zo dicht mogelijk bij uw verwachting te maken om het aantal het vals-positieve komt overeen met laag.

Pas op dat bestanden met nieuwe regels in hun bestandsnamen problemen kunnen veroorzaken met deze aanpak.

Antwoord

Met behulp van perl” s File::LibMagic module:

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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *