Wie finde ich Dateien nach Dateityp?

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 in grep Bourne weiterleiten, wenn Sie nach Bash-Skripten oder grep 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" -- . 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.