Wie finde ich Dateien?

Es gibt mehrere Möglichkeiten. Es kommt auch darauf an, ob man nach Dateiname oder Dateiinhalt suchen will, und was man suchen will. Folgende Möglichkeiten gibt es:

* which
"Wo liegt das Programm, was ausgeführt wird, wenn ich jetzt XYZ tippe?"
  • Vorteil: sehr fix zur Suche von Programmen.

* type

Im Gegensatz zu "which" findet "type" auch die Befehle, die in die Shell eingebaut sind (Buildins). z.B. "echo" ist oft als /bin/echo auf dem System. Wird "echo" eingetippt, wird aber das echo der Shell ausgeführt (sofern in der Shell eingebaut). "type echo" zeigt, welches "echo wirklich ausgeführt wird ;-)

* whereis

Suche nach zusammengehörigen Dateien in Standardpfaden.

* locate

Suche in einer regelmäßig aktualisierten Datenbank.

* find

Suche nach Dateinamen mit Hilfe von tausenden von Kriterien.

* grep

Suche nach Zeichenketten und regulären Ausdrücken innerhalb von Dateien.

* glimpse

* doodle

Locate

Dateien lassen sich in der Konsole wohl am komfortabelsten mit locate suchen. locate dateiname sollte hier recht schnell die gewünschten Ergebnisse liefern. Es benutzt eine Datenbank des gesamten Verzeichnisbaums, sucht also sehr schnell.

Damit locate richtig arbeiten kann, muss eine Datenbank gepflegt, also z.B. ein Mal am Tag aktualisiert werden, was normalerweise automatisch per CronJob erledigt wird. Achtung: locate läuft normalerweise als nobody, das ist ein Benutzeraccount, welcher fast überhaupt nichts darf. D.h falls Du irgendwelche "geheimen" Verzeichnisse bei Dir pflegst, wird locate darin enthaltene Dateien nicht in seine Datenbank aufnehmen (können).

Dafür gibt es einen Ersatz, genannt slocate, der als root läuft, aber die Zugriffsrechte der Dateien mit abspeichert und damit dann das "Finden" von Dateien davon abhängig macht, ob der "Sucher" die Datei auch sehen darf. Einige Distributionen (z.B. RedHat) installieren standardmäßig slocate.

Tipp

Wer mit locate veraltete Ergebnisse erzielt, also Dateien findet, die nicht mehr existieren o.ä., kann die Datenbank mit updatedb (als root!!) aktualisieren. Unter Umständen ist es jedoch praktisch, einfach das von cron verwendete Script zu benutzen, da dort diverse Parameter (z.B. ob Netzwerkdateisysteme oder Wechseldatenträger mitindiziert werden sollen) übergeben werden. /etc/cron.daily/slocate.cron ist das entsprechende Script bei RedHat.

Find

find durchsucht das angegebene Verzeichnis nach entsprechenden Dateien.

find /home/jens -iname "blubb.*"

Suche in meinem HOME nach allen Dateien, die auf blubb.* passen und achte nicht auf Groß/Kleinschreibung (wie sonst ja üblich).

find /usr/doc -type d -maxdepth 2

Suche in /usr/doc nach allen directories und gehe maximal 2 Verzeichnisebenen tiefer.

find / -type f -empty

Suche im gesamten System nach allen leeren Dateien (f=file).

find / -name "*conf" -xdev

Suche auf der Partition, die / enthält, nach *conf, aber gehe nicht in Verzeichnisse, die auf anderen Partitionen liegen.

find / -type f -size +1000k -iname "*.ps" -exec gzip -9 \{\} \;

Suche im gesamten System nach allen Dateien (f), die größer als 1MB sind und in *.ps enden und komprimiere sie. Die Zeichenkette {} wird von find mit dem jeweiligen Dateinamen ersetzt, und zwischendurch gehört ein Semikolon als Befehlstrenner, aber diese Zeichen müssen "durch" zu find gelangen und wenn man sie nicht mit dem Escape-Zeichen \ sozusagen "festnagelt", würden sie von der Shell interpretiert und das wollen wir hier nicht.

Ist alles eigentlich ganz harmlos :-))

Grep

Grep sucht in Dateien nach Inhalten. Der Name kommt von dem Vi-Befehl ":g/re/p", der alle Zeilen ausgibt, in denen der reguläre Ausdruck "re" vorkommt.

Beispiele:

grep socket /etc/*                       sucht in /etc/* nach "socket" in jeder Datei
grep TCP.*IP /etc/rc.d/*                 sucht nach TCP(irgendwas)IP
grep -i "blubb" /home/jens/Ramsch/*.txt  sucht ohne Groß/kleinschreibung zu beachten meinen Ramsch durch

Man kann grep noch sagen, ob und wie er Dateinamen und -inhalt(sausschnitte) bei (Nicht-)Erfolg (nicht) anzeigen soll - das erfährt man alles in den Manual Pages zu grep.

Die regulären Ausdrücke der Shell und der div. Programme unterscheiden sich - leider - etwas und man darf sie nicht mit den Standard-Wildcards verwechseln. So ist z.B. ".*" fuer grep gleich "ein beliebiges Zeichen und genau davon beliebig viele", für die Bash wäre das nur "*". Das ist, wie so vieles, historisch bedingt.

find und grep kombiniert

Oft kommt es vor, dass man in bestimmten Dateien eines Dateibaums eine bestimmte Zeichenkette sucht, das erreicht man mit einer Kombination aus find und grep. Der Trick ist die Verwendung der Option -H bei grep, damit der Dateinamen ausgegeben wird, obwohl grep nur mit einem Dateinamen aufgerufen wird:

Beispiele:

find -cmin -20 -name "*.java" -exec grep -H "static final" \{\} \;
    # Suche nach einer Datei, die "static final" enthält
    # und vor weniger als 20 Minuten geändert wurde.
find -iname "*.txt" -maxdepth 3 -exec grep -H "Huber" \{\} \;
    # Suche nach einer Textdatei, die höchstens
    # in einer Unterverzeichnistiefe von 3 liegt
    # und die "Huber" enthält.

Perfomanter ist jedoch folgendes:

find [verzeichnis] [optionen] -print0 | xargs -0r grep -H <pattern>

Hierbei gibt find alle gefundenen Dateinamen nicht durch \n getrennt, sondern durch \0 getrennt aus. Das ist vorteilhaft, da \n in Dateinamen prinzipiell vorkommen dürfen, \0 jedoch nicht. Nun liest xargs diese Namen von der Eingabe (durch -0) und führt dann grep mit allen gefundenen Namen aus. Das -r (--no-run-if-empty) gibt dabei an, dass grep nicht aufgerufen werden soll, wenn nichts gefunden wurde. Meistens ist -H hierbei nicht notwendig, da mehrere Dateien gefunden werden. Für den Fall, dass es jedoch nur genau eine ist kann man -H bei grep angeben. Der entscheidende Vorteil ist nun, dass grep nicht für jede Datei aufgerufen wird, sondern nur einmal und dann alle von find gefundenen Dateien durchsucht. Das geht viel schneller, da das Erzeugen von neuen Prozessen (fork) relativ aufwendig ist.

grep DIM `find | grep \.c$`

Suche nach dem Wort "DIM" in allen C-Programmen hier und in allen Unterverzeichnissen:

Whereis

whereis durchsucht die Standardpfade nach Binaries (ausführbaren Dateien), Dokumentation, Konfigurationsdateien und Quellcode (sources) eines Programmes, das dem angegebenen Namen entspricht. Beispiel:

$ whereis sendmail
sendmail: /usr/lib/sendmail /usr/lib/sendmail.cf
          /usr/lib/sendmail.hf /etc/sendmail.cf /usr/sbin/sendmail
          /usr/man/man8/sendmail.8.gz

Which

which beantwortet die Frage "wenn ich jetzt XYZ eingebe, wo liegt dann das Programm, welches gestartet wird?". Das ist vor allem nützlich, wenn man mehrere Programme hat, die gleich heißen, und man schnell wissen will, welches nun zuerst im PATH liegt.

Achtung: which weiß nichts über die Shell und deren interne Befehle! Man sollte deshalb vermeiden, ein eigenes Programm test zu nennen, denn es gibt ein Shell-Interna namens test - dann kommt das externe Programm nie zu Potte! ;)

Einige Shells (tcsh) haben einen internen which-Befehl, der dann auch die anderen internen Shell-Befehle kennt. Ob das der Fall ist kann man mit dem Aufruf which which leicht herausfinden.

Anmerkung: Unter bash gibt es den Befehl 'type', der ebenfalls ausführbare Programme im Path sucht. Sowohl 'which' als auch 'type' kennen die Option '-a', die ALLE Programme XYZ findet. Damit sieht man, ob versehentlich 2 Versionen des gleichen Programms installiert sind.

Alternative: grafische Oberfläche

In Zeiten von KDE, GNOME und Co. kann man auch ganz einfach die Suchfunktion der grafischen Oberfläche nutzen. Die Funktion erreicht man zum Beispiel unter: Startmenü => Dateien suchen. Bei Name die Datei eingeben und dann noch den Pfad. Möchte man die gesamte Festplatte durchsuchen, wählt man root. Unter Advanced kann man Text innerhalb von Dateien suchen. Beispiel: Man weiß, dass irgendwo in einer Datei der Ausdruck "Linux-Party am" steht. Dann gibt man diesen Ausdruck bei Advance ein und für den Dateinamen ein * . Somit werden alle Dateien nach dem Ausdruck gesucht und angezeigt.

Desktop Suche

Fragen und Antworten

Frage: Wenn ich unter KDE ab / suchen lasse, endet das immer darin, dass der Arbeitsspeicher (256MB) + Swap gefüllt und das System lahmgelegt wird?

Antwort: vermeide Zugriffe auf /proc/k* !

Frage: Wie suche ich (vermutl. am besten mit find) nach Dateien, die NICHT "foobar" heißen und führe für diese eine Aktion aus? Nur für foobar wäre es einfach: find -name foobar -exec echo hallo {} \; Aber wie geht es für alles außer foobar?

Antwort: Benutze das Ausrufezeichen ! hinter find find ! -name foobar -type d -exec echo hallo {} \; Dabei darf das ! nicht hinter "-name" geschrieben werden. Das wäre eine falsche Syntax.


ToDo: SuchenundFinden einarbeiten, genaue Erklärungen/Beispiele bei den einzelnen Programmen


CategoryCategory

DateienSuchen (zuletzt geändert am 2009-01-17 07:48:58 durch Fce60)