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
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" -- .
--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 naargrep Bourne
leiden als u op zoek was naar bash-scripts ofgrep Perl
als u op zoek was naar Perl-scripts of zoiets.