find ist ein traditionelles Unix-Programm. Es dient zum rekursiven Suchen von Dateien nach bestimmten Kriterien in einem oder mehreren Verzeichnissen. Es ist wirklich nützlich, die Syntax verlangt allerdings etwas Übung:
find [Optionen] [Verzeichnisse] [Kriterium] [Handlung] |
Geben Sie kein Verzeichnis an, durchsucht find das aktuelle Verzeichnis. Geben Sie das Kriterium nicht an, gilt sein Wert als ,,wahr`` und alle Dateien werden gefunden. Die Optionen, Kriterien und Aktionen sind so mannigfaltig, dass hier nur wenige erwähnt werden können. Die Optionen:
-xdev: Durchsuche keine Verzeichnisse auf anderen Dateisystemen.
-mindepth <n>: Gehe mindestens <n> Verzeichnisebenen unter das angegebene Verzeichnis zurück, bevor die Suche gestartet wird.
-maxdepth <n>: Suche nach Dateien, die sich maximal n Verzeichnisebenen unter dem angegebenen Verzeichnis befinden.
-follow: Folge symbolischen Verweisen, die auf Verzeichnisse zeigen. In der Voreinstellung von find wird dies nicht getan.
-daystart: Werden zeit-bezogene Tests durchgeführt (siehe unten), wird der Beginn des aktuellen Tages als Zeitstempel genommen (und nicht der Zeitpunkt vor 24 Stunden, was der Standard-Einstellung entspricht).
Ein Kriterium kann einen oder mehrere atomare Tests umfassen. Einige nützliche Tests:
-type <Typ>: Suche nach einem bestimmten Dateityp. <Typ> kann folgende Werte annehmen: f (reguläre Datei), d (Verzeichnis), l (symbolischer Verweis), s (Socket), b (Blockdatei), c (Zeichendatei) oder p (benannte Umleitung).
-name <Muster>: Finde Dateien, deren Name <Muster> entspricht. Mit dieser Option wird <Muster> wie ein Suchmuster behandelt (siehe Kapitel Suchmuster und Reguläre Ausdrücke).
-iname <Muster>: Wie -name, ignoriert jedoch Groß- und Kleinschreibung.
-atime <n>, -amin <n>: Finde Dateien, auf die zuletzt vor <n> Tagen (-atime) oder <n> Minuten (-amin) zugegriffen wurde. Sie können auch +<n> oder -<n> spezifizieren. Dann wird nach Dateien gesucht, auf die vor höchstens, bzw. mindestens <n> Tagen, bzw. Minuten zugegriffen wurde.
-anewer <Datei>: Findet Dateien auf die später zugegriffen wurde als auf Datei <Datei>
-ctime <n>, -cmin <n>, -cnewer <Datei>. Genau wie -atime, -amin und -anewer, doch in Bezug auf die letzte Inhaltsänderung der Datei.
-regex <Muster>: Wie -name, jedoch wird hier Muster als regulärer Ausdruck behandelt.
-iregex <Muster>: Wie -regex, ignoriert aber Groß- und Kleinschreibung.
Es gibt noch eine Menge anderer Tests, wie Sie im Handbuchauszug zu find nachlesen können. Sie können Tests auch miteinander kombinieren:
<c1> -a <c2>: Wahr, wenn beide, <c1> und <c2>, wahr sind. -a wird bereits implizit aktiviert, daher brauchen Sie nur <c1> <c2> <c3>... eingeben, wenn Sie alle Tests <c1>, <c2>,... durchführen möchten.
<c1> -o <c2>: Wahr, wenn entweder <c1>, <c2> oder beide wahr sind. -o hat eine geringere Wertigkeit als -a. Wenn Sie also Dateien möchten, die Kriterium <c1> oder <c2> und Kriterium <c3> entsprechen, müssen Sie Klammern verwenden: ( <c1>-o <c2> ) -a <c3>. Damit die hier verwendeten Klammern nicht von Ihrer Shell interpretiert werden, müssen Sie sie durch Voranstellen eines Rückstriches (\) schützen.
-not <c1>: Invertiert den Test <c1>. Also ist -not <c1> wahr, wenn <c1> falsch ist.
Schließlich können Sie noch Aktionen für gefundene Dateien angeben. Oft benutzt werden:
-print: Gibt den Namen jeder Datei auf die Standard-Ausgabe aus (das ist die Standard-Aktion).
-ls: Gibt das Äquivalent von ls -ilds für jede gefundene Datei auf die Standard-Ausgabe aus.
-exec <Kommando>: Führt den Befehl <Kommando> für jede gefundene Datei aus. Die Zeile <Kommando> muss mit einem Semikolon (;) enden, welches Sie vor der Interpretation durch die Shell schützen müssen. Schauen Sie sich die Beispiele an.
-ok <Kommando>: Wie -exec aber interaktiv.
Noch da? Gut – ein bisschen Übung wird Ihnen helfen, sich mit diesem Monsterkommando zurechtzufinden. Angenommen, Sie möchten eine Liste der Verzeichnisse in /usr/share erhalten, dann tippen Sie:
find /usr/share -type d |
Angenommen, Sie haben einen HTTP-Server und alle Ihre HTML-Dateien befinden sich in /home/httpd/html, wo Sie sich auch gerade befinden. Sie möchten eine Liste aller Dateien, deren Inhalt seit einem Monat nicht verändert worden ist. Da die Seiten von verschiedenen Schreibern stammen, enden einige auf html und einige auf htm. Sie möchten diese Dateien in das Verzeichnis /home/httpd/obsolete verknüpfen. Geben Sie folgendes ein:[1]
find \( -name "*.htm" -o -name "*.html" \) -a -ctime -30 -exec ln {} /home/httpd/obsolete \; |
Gut, das hier ist etwas komplex und verlangt nach Erklärung. Das Suchkriterium ist Folgendes:
\( -name "*.htm" -o -name "*.html" \) -a -ctime -30 |
Es findet alle Dateien, die entweder auf .htm oder auf .html enden (( -name "*.htm" -o -name "*.html" )) und (-a) die in den letzten 30 Tagen nicht modifiziert wurden (-ctime -30). Beachten Sie die Klammern, die hier notwendig sind, da -a eine höhere Wertigkeit hat. Ließen Sie sie weg, würde das Kommando alle Dateien mit der Endung .htm finden sowie die Dateien, die auf .html enden und seit einem Monat nicht modifiziert wurden. Beachten Sie auch, dass die Klammern vor der Shell geschützt wurden. Gäben Sie ( .. ) anstelle von \( .. \) ein, würde die Shell versuchen, diese zu interpretieren und das Kommando -name "*.htm" -o -name "*.html" in einer Sub-Shell auszuführen. Sie können diesen Schutz übrigens auch durch Anführungszeichen erreichen.
Und schließlich das Kommando, das für jede gefundene Datei ausgeführt wird:
-exec ln {} /home/httpd/obsolete \; |
Auch hier müssen Sie das ; vor der Shell schützen, da diese es sonst als Kommandoseparator interpretiert und find sich beschweren wird, dass -exec ein Argument fehlt.
Ein letztes Beispiel: Sie haben ein großes Verzeichnis mit allen möglichen Bilddateien: /shared/images. Normalerweise benutzen Sie touch, um den Zeitstempel einer Datei namens stamp in diesem Verzeichnis aufzufrischen, um eine Zeitreferenz zu haben. Sie wollen eine Liste aller JPEG-Dateien, die jünger als die Datei stamp sind. Da Sie die Dateien von verschiedenen Quellen haben, haben Sie die Endungen jpg, jpeg, JPG oder JPEG. Sie möchten nicht im Verzeichnis old suchen, Sie möchten diese Liste zugeschickt bekommen und Ihr Benutzername ist john:
find /shared/images -cnewer \ /shared/images/stamp \ -a -iregex ".*\.jpe?g" \ -a -not -regex ".*/old/.*" \ | mail john -s "Neue Images" |
Und das war's! Nun wäre es nicht sehr schön, dieses Kommando regelmäßig neu eingeben zu müssen, also brauchen Sie...:
[1] | Denken Sie daran, dass in diesem Beispiel beide Verzeichnisse auf dem selben Dateisystem sein müssen! |