Ich weiß, dass ich Dateien mit find
finden kann: find . -type f -name "sunrise"
. Beispielergebnis:
./sunrise ./events/sunrise ./astronomy/sunrise ./schedule/sunrise
Ich weiß auch, dass ich den Dateityp einer Datei bestimmen kann: file sunrise
. Beispielergebnis:
sunrise: PEM RSA private key
Aber wie kann ich Dateien nach Dateityp finden?
Zum Beispiel my-find . -type f -name "sunrise" -filetype=bash-script
:
./astronomy/sunrise ./schedule/sunrise
Kommentare
- Es gibt kein
--filetype
Option für den Befehl find oder irgendetwas anderes, das Ihnen den Dateityp angibt. Sie können nur--exec file {} \;
verwenden und dann ingrep Bourne
weiterleiten, wenn Sie nach Bash-Skripten odergrep Perl
, wenn Sie nach Perl-Skripten oder Ähnlichem gesucht haben.
Antwort
„Dateitypen“ auf einem Unix-System sind Dinge wie reguläre Dateien, Verzeichnisse, Named Pipes, spezielle Zeichendateien, symbolische Links usw. Dies sind die Typen von Dateien, nach denen find
mit der Option -type
filtern kann.
Die find
kann selbst nicht zwischen einem „Shell-Skript“, einer „JPEG-Bilddatei“ oder einem anderen Typ einer regulären Datei unterscheiden. Diese Datentypen können jedoch durch das Dienstprogramm file
unterschieden werden, das bestimmte Signaturen in den Dateien selbst untersucht, um ihren Typ zu bestimmen.
Eine gebräuchliche Methode zum Beschriften Die verschiedenen Arten von Datendateien werden anhand ihres MIME-Typs erstellt, und file
kann den MIME-Typ von a bestimmen Datei.
Verwenden Sie file
mit find
, um den MIME-Typ regulärer Dateien zu erkennen, und verwenden Sie diesen So finden Sie nur Shell-Skripte:
find . -type f -exec sh -c " case $( file -bi "$1" ) in */x-shellscript*) exit 0 esac exit 1" sh {} ";" -print
oder mit bash
find . -type f \ -exec bash -c "[[ "$( file -bi "$1" )" == */x-shellscript* ]]" bash {} ";" \ -print
Fügen Sie -name sunrise
vor -exec
hinzu, wenn Sie nur Skripte mit diesem Namen erkennen möchten.
Der obige Befehl find
findet alle regulären Dateien im oder unter dem aktuellen Verzeichnis und ruft für jede dieser Dateien ein kurzes Inline-Shell-Skript auf. Dieses Skript führt file -bi
für die gefundene Datei aus und wird mit einem Exit-Status von Null beendet, wenn die Ausgabe dieses Befehls die Zeichenfolge /x-shellscript
enthält. Wenn die Ausgabe diese Zeichenfolge nicht enthält, wird sie mit einem Exit-Status ungleich Null beendet, wodurch find
sofort mit der nächsten Datei fortfährt. Wenn festgestellt wurde, dass es sich bei der Datei um ein Shell-Skript handelt, gibt der Befehl find
den Pfadnamen der Datei aus (die -print
am end (das auch durch eine andere Aktion ersetzt werden könnte).
Der Befehl file -bi
gibt den MIME-Typ der Datei aus. Für ein Shell-Skript unter Linux ( und die meisten anderen Systeme) wäre dies so etwas wie
text/x-shellscript; charset=us-ascii
auf Systemen mit einer etwas älteren Variante des file
kann
application/x-shellscript
sein. Das gemeinsame Bit ist die /x-shellscript
Teilzeichenfolge.
Beachten Sie, dass Sie unter macOS aus Gründen file -bI
anstelle von file -bi
verwenden müssen Die Option -i
bewirkt etwas ganz anderes. Die Ausgabe unter macOS ähnelt der eines Linux-Systems.
Möchten Sie eine benutzerdefinierte Aktion ausführen? Auf jedem gefundenen Shell-Skript können Sie th tun at mit einem anderen -exec
anstelle des -print
in den obigen Befehlen find
, aber es wäre auch möglich,
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 {} +
oder mit 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 {} +
Verwandte Themen:
Antwort
Sie können find
für jede gefundene Datei ausführen und dann nach dem Ergebnis suchen, an dem Sie interessiert sind.
# When looking for ASCII Text find . -type -exec file {} \; | grep "ASCII" # or for MS Word Documents find . -type f -exec file {} \; | grep "Microsoft Word"
Ich schlage vor, das Suchmuster so nah wie möglich an Ihre Erwartung zu bringen, die Anzahl von beizubehalten Das falsch positive Ergebnis ist niedrig.
Beachten Sie, dass Dateien mit Zeilenumbrüchen in ihren Dateinamen Probleme mit diesem Ansatz verursachen können.
Antwort
Verwenden von 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" -- .