Linux & Co.

Linux-Terminal-Basics 8: Suchen in/von Dateien

Finden ist im Terminal ziemlich präzise, leider ist ausgerechnet der Spezialist eher unschön

Egal, ob Ihr nun Dateien bestimmten Alters sucht, alle Schreibweisen von Meier in Tausenden Textdokumenten, MP3-Dateien in einem bestimmten Subordner oder einfach nur foobar.txt, mit zwei Standard-Tools lässt sich das prima erledigen. Nun, eigentlich sind es drei Tools: find, grep und reguläre Ausdrücke.

In unserer Serie zu Linux-Terminal-Basics zeigen wir Euch, wie Ihr einige der wichtigsten Aufgaben auf der Kommandozeile erledigen könnt - vom Navigieren, über Dateioperationen, bis hin zu komplexen Suchaufträgen. Als Terminal verwenden wir Bash und auch wenn Linux im Vordergrund steht, funktioniert fast alles auch unter Windows. Und nun noch die Links zur Einleitung und zur Übersicht aller Artikel.

Kurz vorweg: Regex

Reguläre Ausdrücke, auch Regular Expressions oder kurz Regexe, beschreiben ein Muster, eine bestimmte Abfolge von Zeichen. Das kann etwas Einfaches sein wie Zeilen, die mit dem Buchstaben M anfangen oder auch eine Definition aller möglichen Meier-Schreibweisen (Meyer, Maier etc.). Mit einer Suche nach letzterer Regex könnte man zum Beispiel in riesigen Dokumentenmengen nach allen Vorkommen dieses Familiennamens fahnden. Und wenn Euer Mediacenter Staffel- und Folgenummern bei Serien erkennt - oder überhaupt Titel -, liegt das in der Regel auch an Regexen.

Nun sind Regexe wirklich super, aber nichts für eine Basics-Serie. Einen recht ausführlichen - nicht immer ganz ernsten - Artikel zu dem Thema haben wir allerdings. Im Folgenden wird daher ohne dieses Wundermittel gesucht, Platzfreihalter wie das * gibt es natürlich dennoch. Das fällt dann unter das Thema Shell Globbing, das für alle Tools in der Bash zur Verfügung steht.

In Dateien suchen

Weil einfacher, zunächst mal die Volltextsuche: Das Werkzeug der Wahl ist hier grep. Grep sucht einfach Zeile für Zeile nach dem gesuchten Begriff und gibt, standardmäßig, diese Zeilen aus - auf Wunsch mit hervorgehobenem Suchbegriff. Um etwa nach foobar in der Datei mein-text.txt zu suchen:

grep foobar mein-text.txt

Oder wie wäre es mit foobar oder meier in allen TXT-Dateien:

grep "foobar|meier" *.txt

Das Pipe-Symbol (|) funktioniert hier wie so häufig als ODER-Verknüpfung und das Sternchen natürlich als Platzhalter für eine beliebige Zeichenfolge.

Es gibt ein paar wenige Optionen von grep, die Ihr wirklich kennen solltet:

grep -i - ignoriert Groß-/Kleinschreibung
grep -o - gibt nur die Treffer aus (statt Zeilen)
grep -A 2 -B 2 - gibt 2 Zeilen vor und nach dem Treffer mit aus
grep -c - zählt lediglich die Treffer
grep -n - gibt Zeilennummern mit aus

Und für denn Alltag genügt das eigentlich schon. Weitere Beispiele findet Ihr über unsere hauseigene Linux-Hilfe cli.help direkt im Terminal:

curl cli.help/grep

Dateien suchen

Tja, die Dateisuche ... Das Tool ist wundervoll, nur leider ist die Syntax nicht wirklich intuitiv und so schnell vergessen. Das Tool heißt passend find und sucht beispielsweise so nach Dateien namens foobar im Namen:

find -name foobar

Schon diese Basisform ist "schwer" merkbar, weil man die Option name angeben muss. Der Grund ist gut, man kann eben auch nach anderen Eigenschaften wie dem Dateialter suchen. In der Form würden auch wirklich nur Dateien unterhalb des aktuellen Ordners gefunden, die exakt foobar heißen. Tipp: Wenn Groß-/Kleinschreibung ignoriert werden soll - Danke für den Kommentar -, könnt Ihr -iname verwenden (ganz ähnlich also wie oben bei grep).

Vermutlich sucht Ihr eher nach allen Dateien, die foobar enthalten - und dann wird es noch etwas länger:

find ./ -name "*foobar*"

Drei Änderungen: Zunächst folgt nach dem Befehl der Pfad - bei Suchen nach Ausdrücken (keine Regex) muss dieser davor stehen, auch wenn das aktuelle Verzeichnis gemeint ist. Dann folgt der Ausdruck: Dieser soll (muss ...) in Anführungszeichen stehen und die Sternchen stehen abermals als Platzhalter für beliebige Zeichenfolgen.

Nächste übliche Aufgabe: ODER-Verknüpfung schon wieder - und zwar in mehreren Verzeichnissen. Gesucht werden soll nach Dateien, die foobar im Namen enthalten oder in den letzten 10 Tagen bearbeitet wurden:

find ~/backups ~/dateien -name "*foobar* -o -mtime -10

Es genügt also ein simples -o als ODER. Als zweite Option wird hier nach einer Modifikationszeit (mtime) kleiner als 10 (Tage) gesucht. Hier seht Ihr auch ganz praktisch, warum immer die name-Option angegeben werden muss - es kann halt nach anderen Eigenschaften gesucht werden. Statt einer ODER- könnt Ihr natürlich auch eine UND-Verknüpfung nutzen - wenig überraschend mit -a (ist aber auch implizit).

Das Tool kann noch viel viel mehr, aber für den Alltag genügt es, noch eine weitere Option zu lernen:

find ./ foobar -maxdepth 2

Mit maxdepth beschränkt Ihr, wie viele Hierarchiestufen gesucht wird. Alle Optionen zusammen könnten dann zum Beispiel diesen durchaus alltäglichen Suchauftrag formulieren:

find ./ -maxdepth 2 \( -name "foo*" -o -name "backup*" -a -mtime -3 \) -a -type d

Gefunden würden: Ordner (-type d) im aktuellen oder direkten Unterordner (maxdepth), die mit foo anfangen - oder mit backup anfangen und zusätzlich vor maximal 3 Tagen zuletzt bearbeitet wurden. Wie gesagt, es artet in Tipperei aus ... Die wirklichen Basics habt Ihr da aber schon verlassen, zumal auch noch Klammern hinzugekommen sind (die ein doppeltes "-type d" ersparen - wenn Ihr wissen wollt wie, dann fragt ;) ).

Das soll so weit genügen, aber mal als Ausblick, (aka Abschreckung) warum es sich lohnt, sich find zu erarbeiten:

find ./ -regextype posix-extended -maxdepth 1 -regex '\.\/(foo.*|bar.*)' -printf '%f\n'

Ist selbsterklärend, oder? ;) Das eigentlich Coole ist das exec am Ende: Was auch immer Ihr findet, könnt Ihr auch direkt mit einem beliebigen anderen Programm weiterverarbeiten. Hier würden alle Namen der im aktuellen Ordner gefundenen TXT-Dateien, die mit ./foo oder ./bar beginnen, über das Programm cowsay ausgegeben - also in der Sprechblase einer ASCII-Kuh. Natürlich.

ne ascii-kuh.
Yep

Am Ende noch eine gute Nachricht: Falls Ihr Programme sucht, gibt es dafür wieder einen einfachen Weg:

whereis echo
which echo

whereis zeigt alle Pfade zu allen Installationen des Programms echo und which zeigt den Pfad zu der tatsächlich verwendeten Installation.

Mehr zur Kommandozeile.

Mirco Lang

Freier Journalist, Exil-Sauerländer, (ziemlich alter) Skateboarder, Dipl.-Inf.-Wirt, Einzelhandelskaufmann, Open-Source-Nerd, Checkmk-Handbuchschreiber. Ex-Saturn'ler, Ex-Data-Becker'ler, Ex-BSI'ler. Computer-Erstkontakt: ca. 1982 - der C64 des großen Bruders eines Freunds. Wenn Ihr hier mehr über Open Source, Linux und Bastelkram lesen und Tutonaut unterstützen möchtet: Über Kaffeesponsoring via Paypal.freue ich mich immer. Schon mal im Voraus: Danke! Nicht verpassen: cli.help und VoltAmpereWatt.de. Neu: Mastodon

2 Kommentare

    1. Danke – auch für den i-Tipp, habe ich übernommen. Hätte ich auch gleich drauf kommen können, bei grep hatte ich noch drauf hingewiesen …

      In der ersten Form fehlt die Pfadangabe absichtlich. Sucht man nicht nach einem Pattern, sondern nur nach dem wörtlichen String, funktioniert das auch ohne Pfad.

Schreibe einen Kommentar

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

Schaltfläche "Zurück zum Anfang"