Jag vet att jag kan hitta filer med find
: find . -type f -name "sunrise"
. Exempel på resultat:
./sunrise ./events/sunrise ./astronomy/sunrise ./schedule/sunrise
Jag vet också att jag kan bestämma filtypen för en fil: file sunrise
. Exempel på resultat:
sunrise: PEM RSA private key
Men hur kan jag hitta filer efter filtyp?
Till exempel my-find . -type f -name "sunrise" -filetype=bash-script
:
./astronomy/sunrise ./schedule/sunrise
Kommentarer
Svar
”Filtyper” på ett Unix-system är saker som vanliga filer, kataloger, namngivna rör, karaktärspecifika filer, symboliska länkar etc. Det här är typen av filer som find
kan filtrera vidare med alternativet -type
.
find
verktyget kan inte i sig skilja mellan ett ”skalskript”, ”JPEG-bildfil” eller någon annan typ av vanlig fil . Dessa typer av data kan emellertid särskiljas av verktyget file
, som tittar på särskilda signaturer i själva filerna för att bestämma deras typ.
Ett vanligt sätt att märka de olika typerna av datafiler är enligt deras MIME-typ , och file
kan bestämma MIME-typen för en fil.
Använd file
med find
för att upptäcka MIME-typen av vanliga filer och använd den för att bara hitta skalskript:
find . -type f -exec sh -c " case $( file -bi "$1" ) in */x-shellscript*) exit 0 esac exit 1" sh {} ";" -print
eller med bash
,
find . -type f \ -exec bash -c "[[ "$( file -bi "$1" )" == */x-shellscript* ]]" bash {} ";" \ -print
Lägg till -name sunrise
före -exec
om du bara vill upptäcka skript med det namnet.
Kommandot find
ovan hittar alla vanliga filer i eller under den aktuella katalogen, och för varje sådan fil anropas ett kort in-line skalskript. Det här skriptet kör file -bi
på den hittade filen och avslutas med nollutgångsstatus om utdata från det kommandot innehåller strängen /x-shellscript
. Om utdata inte innehåller den strängen, avslutas den med en utgångsstatus som inte är noll vilket gör att find
fortsätter omedelbart med nästa fil. Om filen visade sig vara ett skalskript, kommer kommandot find
att fortsätta att mata ut filens sökväg (-print
vid slut, som också kan ersättas av någon annan åtgärd).
Kommandot file -bi
skickar MIME-typen av filen. För ett skalskript på Linux ( och de flesta andra system) skulle detta vara ungefär som
text/x-shellscript; charset=us-ascii
medan det är på system med en något äldre variant av file
-verktyg, det kan vara
application/x-shellscript
Den gemensamma biten är /x-shellscript
-strängen.
Observera att på macOS måste du använda file -bI
istället för file -bi
på grund av skäl ( -i
-alternativet gör något helt annat). Utdata på macOS liknar det för ett Linux-system.
Vill du utföra en anpassad åtgärd på varje hittat skalskript kan du göra det at med en annan -exec
i stället för -print
i find
kommandona ovan, men det skulle det också vara möjligt att göra
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 {} +
Relaterat:
Svar
Du kan köra find
på varje hittad fil och sedan grep för det resultat du är intresserad av.
# When looking for ASCII Text find . -type -exec file {} \; | grep "ASCII" # or for MS Word Documents find . -type f -exec file {} \; | grep "Microsoft Word"
Jag föreslår att du gör sökmönstret så nära din förväntan att behålla antalet de falska positiva matchningarna är låga.
Observera att filer med nya rader i deras filnamn kan orsaka problem med detta tillvägagångssätt.
Svar
Med 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" -- .
--filetype
-alternativ för sökkommandot eller något annat som berättar vilken typ av fil. Det enda du kan göra är att använda--exec file {} \;
och sedan rör det tillgrep Bourne
om du letade efter bash-skript ellergrep Perl
om du letade efter Perl-skript eller något i den riktningen.