Finde Text in Dateien unter Linux
Volltextsuche unter Linux: Text in Dateien finden mit grep, find und xargs, ripgrep als schnelle Alternative, zgrep für Archive und locate für Dateinamen.
Immer wieder frage ich mich, in welcher der Konfigurationsdateien ein gewisser Text steht. Die Antwort liefert unter Linux fast immer grep, ergänzt um find, ripgrep oder locate. Hier die Werkzeuge, die ich täglich verwende, mit echten Befehlszeilen.
grep-Grundlagen
Der Standardaufruf für eine Volltextsuche über einen Verzeichnisbaum:
grep -r "suchbegriff" /pfad
Das durchsucht alle Dateien unterhalb von /pfad und gibt Dateiname und Fundzeile aus. Setz den Suchbegriff in Anführungszeichen, sobald Leerzeichen, Sternchen oder Dollarzeichen darin vorkommen, sonst frisst die Shell das Muster, bevor grep es sieht.
Ein typisches Beispiel aus meinem Alltag, die Suche nach einer Domain in allen vhosts:
grep -rn "wermescher.com" /etc/apache2/sites-available/
Die wichtigsten grep-Optionen
| Option | Wirkung |
|---|---|
-r | rekursiv durch alle Unterverzeichnisse |
-i | Groß- und Kleinschreibung ignorieren |
-n | Zeilennummer des Treffers ausgeben |
-l | nur die Dateinamen ausgeben, nicht die Zeilen |
-w | nur ganze Wörter treffen |
-c | Anzahl der Treffer je Datei zählen |
-v | invertieren, also alle Zeilen ohne Treffer |
--include | nur Dateien nach Muster durchsuchen, etwa --include='*.conf' |
--exclude | Dateien nach Muster überspringen |
--exclude-dir | ganze Verzeichnisse überspringen, etwa --exclude-dir=.git |
-A n | n Zeilen nach dem Treffer mit ausgeben |
-B n | n Zeilen vor dem Treffer mit ausgeben |
-C n | n Zeilen davor und danach |
-E | erweiterte reguläre Ausdrücke |
-F | Muster als festen Text behandeln, keine Sonderzeichen |
Kombiniert ergibt das kompakte Aufrufe. Alle .conf-Dateien nach well-known durchsuchen, Groß- und Kleinschreibung egal, mit Zeilennummer:
grep -rni --include='*.conf' "well-known" /etc/apache2/
Nur wissen, welche Dateien betroffen sind:
grep -rl "DocumentRoot" /etc/apache2/sites-available/
Kontext ist Gold wert, wenn Du einen Konfigurationsblock suchst und die umliegenden Direktiven brauchst:
grep -rn -C 5 "SSLCertificateFile" /etc/apache2/sites-available/
Und -v hilft beim Aufräumen, etwa um eine Konfigurationsdatei ohne Kommentare und Leerzeilen zu lesen:
grep -v -E '^\s*(#|$)' /etc/ssh/sshd_config
Statt eines festen Suchbegriffs kannst Du grep auch mit Mustern füttern — wie das geht, zeigt der Beitrag zu regulären Ausdrücken mit grep.
grep mit find und xargs kombinieren
grep -r reicht meistens. Sobald Du aber nach Dateieigenschaften filtern willst, also nach Alter, Größe, Besitzer oder Rechten, übernimmt find die Vorauswahl und übergibt an grep.
Die ursprüngliche Variante mit -exec:
cd /etc/apache2/sites-available/
find . -type f -name '*.conf' -exec grep -H 'well-known' {} \;
-H erzwingt die Ausgabe des Dateinamens, weil grep bei einer einzelnen Datei sonst nur die Zeile zeigt. Der Nachteil: -exec … \; startet für jede Datei einen eigenen grep-Prozess. Bei tausenden Dateien wird das spürbar langsam. Zwei schnellere Wege:
find . -type f -name '*.conf' -exec grep -Hn 'well-known' {} +
find . -type f -name '*.conf' -print0 | xargs -0 grep -Hn 'well-known'
Das + am Ende sammelt möglichst viele Dateien für einen Aufruf. Bei xargs sorgt das Paar -print0 und -0 dafür, dass Leerzeichen und Umlaute in Dateinamen nicht zum Problem werden.
Ein Beispiel mit echtem Mehrwert, alle in den letzten zwei Tagen geänderten Logdateien nach einer IP durchsuchen:
find /var/log -type f -name '*.log' -mtime -2 -print0 \
| xargs -0 grep -Hn '203.0.113.'
Wie Du Dateien nach Größe eingrenzt, steht in Dateien ab einer bestimmten Größe finden.
ripgrep als schnelle Alternative
Für große Verzeichnisbäume und vor allem für Quellcode nutze ich ripgrep. Es durchsucht parallel, ist deutlich schneller als grep und überspringt von sich aus alles, was in einer .gitignore steht, dazu versteckte Dateien und Binärdateien.
Installation:
sudo apt install ripgrep
Der Aufruf ist kürzer, weil rekursiv und Zeilennummern die Voreinstellung sind:
rg "suchbegriff"
rg -i "TODO" src/
rg -t yaml "image:"
rg --hidden --no-ignore "api_key"
-t filtert nach Dateityp, --hidden --no-ignore schaltet die Ignorierregeln ab, wenn Du wirklich alles sehen willst. Genau diese Voreinstellungen sind der Punkt: In einem Repository mit node_modules liefert grep -r tausende irrelevante Treffer, rg von Haus aus nur die aus dem eigenen Code.
Für die restlichen Fälle bleibt grep die richtige Wahl, weil es auf jedem System vorhanden ist. Auf einem fremden Server willst Du keine Pakete installieren, nur um eine Zeile zu suchen.
Suche in Archiven und komprimierten Dateien
Rotierte Logs liegen als .gz vor. Dafür gibt es die z-Varianten der üblichen Werkzeuge, die vor der Suche transparent entpacken:
zgrep "Fehler" /var/log/syslog.*.gz
zgrep -i "203.0.113.7" /var/log/apache2/access.log.*.gz
Passend dazu gibt es zcat, zless und zdiff. Für bzip2 heißen sie bzgrep, für xz xzgrep. Praktisch ist die Kombination aus beidem, um laufende und archivierte Logs in einem Rutsch zu prüfen:
grep -h "Fehler" /var/log/syslog; zgrep -h "Fehler" /var/log/syslog.*.gz
In tar-Archiven sucht grep nicht direkt. Dort listest Du entweder den Inhalt mit tar -tf oder entpackst nach stdout:
tar -xzOf backup.tar.gz | grep -a "suchbegriff"
Mehr zum Umgang mit Archiven findest Du unter zip, unzip und tar unter Linux.
Dateinamen statt Inhalt suchen
Manchmal suchst Du keine Textstelle, sondern die Datei selbst. Dafür ist find zuständig:
find /etc -type f -name 'ssl*.conf'
find /home -type f -iname '*.pdf'
find / -type f -name 'php.ini' 2>/dev/null
Das 2>/dev/null unterdrückt die Meldungen zu Verzeichnissen ohne Leserechte. find läuft dabei jedes Mal über das Dateisystem, was auf großen Platten dauert.
Schneller geht es mit einem Index. locate beziehungsweise dessen aktueller Nachfolger plocate fragt eine Datenbank ab und antwortet praktisch sofort:
sudo apt install plocate
sudo updatedb
locate php.ini
locate -i lebenslauf
Der Haken ist die Aktualität: Die Datenbank wird per Timer einmal täglich erneuert. Dateien, die Du gerade angelegt hast, findet locate erst nach einem manuellen sudo updatedb.
Volltextsuche über den ganzen Rechner
Eine echte Volltextsuche über alle Inhalte einer Platte ist etwas anderes als ein grep -r /. Letzteres liest bei jedem Aufruf sämtliche Dateien und dauert je nach Datenmenge Stunden. Für den einmaligen Fall geht das:
sudo grep -rIl "Vertragsnummer 4711" /home --exclude-dir={.cache,.git,node_modules}
-I überspringt Binärdateien, -l liefert nur die Dateinamen, und die ausgeschlossenen Verzeichnisse sparen den Großteil der Laufzeit.
Suchst Du hingegen regelmäßig in denselben Beständen, lohnt ein Index. Sinnvoll wird das ab etwa der Größenordnung eines gut gefüllten Home-Verzeichnisses oder eines Dokumentenarchivs, und immer dann, wenn Du auch in PDFs, Office-Dokumenten und Mails suchen willst. Ein Index extrahiert deren Text einmal und beantwortet Anfragen danach in Millisekunden.
Auf dem Desktop übernimmt das unter GNOME der Tracker, unter KDE Baloo, beides ist bereits aktiv. Für Server und größere Dokumentenbestände greife ich zu Recoll, das lokal indiziert und Formate wie PDF, ODT und DOCX mit abdeckt.
Die Faustregel, nach der ich entscheide: Einmalige Suchen, klar eingegrenzte Verzeichnisse und Quellcode gehören zu grep oder ripgrep. Wiederkehrende Suchen über viele Formate und große Bestände gehören in einen Index. Alles dazwischen erledigt locate für Namen und grep --include für Inhalte.
Verwandte Beiträge
Mehr aus „Linux, DevOps & Systeme"
Docker Speicherplatz freigeben
Docker Speicherplatz freigeben: mit docker system df die Belegung sehen und mit prune ungenutzte Images, Container, Volumes und Build-Cache löschen.
WeiterlesenWindows Core Prozesse verstehen
Windows Core-Prozesse verstehen: was smss.exe, csrss.exe, lsass.exe und svchost.exe wirklich tun und woran Du getarnte Malware im Prozessbaum erkennst.
WeiterlesenUbuntu LTS Release Update
Ubuntu LTS sicher aktualisieren: Snapshot bei Contabo oder Netcup anlegen, mit apt update und do-release-upgrade hochziehen und den SSH-Port bestätigen.
WeiterlesenÜber diesen Blog
Ein Sammelsurium an Denkanstößen.
Hier sammle ich Wissen, Argumente und Links zu allem, was mich beschäftigt — von Technik über Küche bis Nachhaltigkeit. Beruflich berate ich zu Cybersecurity.