Wie durchsuche ich das gesamte Dateisystem nach Text?

53

Unter der Annahme, dass das grep-Tool verwendet werden soll, möchte ich im gesamten Dateisystem nach der Textzeichenfolge "800x600" suchen.

Ich habe es versucht:

grep -r 800x600 /

aber es geht nicht.

Was ich glaube, dass mein Befehl tun sollte, ist rekursiv durch alle Dateien / Ordner unter root nach dem Text "800x600" zu suchen und die Suchergebnisse aufzulisten.

Was mache ich falsch?

Level1Coder
quelle
2
Und mit "es funktioniert nicht" meinen Sie genau was? Druckt es keine Ausgabe, hängt oder druckt es viele Permission deniedFehler? Haben Sie es als root oder als normaler Benutzer ausgeführt?
Alex
Ich bekomme eine gewisse Zugkraft, zuerst befand ich mich in meinem Benutzerverzeichnis, um den Befehl auszuführen. Also habe ich jetzt eine CD / raus zum rooten. Als nächstes habe ich den gleichen Befehl wie oben ausprobiert und es werden viele Fehler mit verweigerten Berechtigungen angezeigt. Ok, jetzt probiere ich sudo grep -r 800x600 / aus und bekomme dann einen / proc / sysrq-Trigger: Eingabe / Ausgabefehler
Level1Coder
Hmm, ich weiß nicht warum es nicht funktionieren würde. Sie können Zugriffsfehler ignorieren, indem Sie tun grep -r 800x600 / 2>/dev/null. Sie können es auch als root ausführen.
Totor

Antworten:

64

Normalerweise verwende ich diesen Befehlsstil, grepum eine Reihe von Dateien zu überfliegen:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

Tatsächlich wird eine Liste aller Dateien auf dem System erstellt und anschließend für jede Datei grepmit den angegebenen Argumenten und dem Namen jeder Datei ausgeführt.

Das -xdevArgument sagt find, dass es andere Dateisysteme ignorieren muss - dies ist gut, um spezielle Dateisysteme wie zu vermeiden /proc. Es werden jedoch auch normale Dateisysteme ignoriert. Wenn sich Ihr / home-Ordner beispielsweise auf einer anderen Partition befindet, wird er nicht durchsucht find / /home -xdev ....

-type fbedeutet, dass nur nach Dateien gesucht wird. Verzeichnisse, Geräte und andere spezielle Dateien werden ignoriert (es wird weiterhin in Verzeichnisse umgewandelt und grepauf die darin enthaltenen Dateien angewendet - es wird nur nicht grepauf das Verzeichnis selbst angewendet , was ohnehin nicht funktioniert). Und die -HOption, ihn grepanzuweisen, immer den Dateinamen in seiner Ausgabe zu drucken.

findAkzeptiert alle Arten von Optionen zum Filtern der Dateiliste. Zum Beispiel -name '*.txt'verarbeitet nur Dateien in TXT - Endung. -size -2Mbedeutet Dateien, die kleiner als 2 Megabyte sind. -mtime -5bedeutet Dateien, die in den letzten fünf Tagen geändert wurden. Fügen Sie diese zusammen mit -a für und -o für oder hinzu und verwenden Sie '('Klammern ')', um Ausdrücke zu gruppieren (in Anführungszeichen, um zu verhindern, dass die Shell sie interpretiert). Also zum Beispiel:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

Schauen man findSie sich die vollständige Liste der möglichen Filter an.

Richard Downer
quelle
2
Beachten Sie, dass -xdevausschließen alle anderen Dateisysteme, nicht nur spezielle. (Wenn Sie /homebeispielsweise eine separate Partition gemountet haben , wird diese nicht durchsucht.)
cjm
Ich habe versucht, jeden find: paths must precede expression: /
auszuführen,
1
Hinweis: Wenn reguläre Ausdrücke nicht erforderlich sind, ist 'fgrep' erheblich schneller als 'grep', was einen großen Unterschied macht, wenn Sie einen großen Baum suchen.
Nathan Kidd
1
Sie können vermeiden, xargsmit vielleicht besserer Effizienz durchzuhalten, indem Sie dies tun find / -xdev -type f -exec grep -H '800x600' +.
Totor
3
Nein, das +Zeichen am Ende des findBefehls bewirkt dasselbe wie xargs: Es erzeugt einen grepProzess mit mehreren Argumenten.
Totor
14

Normalerweise würden Sie nicht wirklich ALLES auf dem System suchen wollen. Linux verwendet Dateiknoten für alles, so dass einige "Dateien" nicht unbedingt durchsucht werden sollten. Zum Beispiel /dev/sdaist das physische Blockgerät für Ihre erste Festplatte. Sie möchten wahrscheinlich die gemounteten Dateisysteme durchsuchen, nicht das Raw-Plattengerät. Es gibt /dev/randomauch Daten, die bei jedem Lesen zufällig ausgespuckt werden. Eine Suche, die wenig Sinn macht. Das /procDateisystem ist in Ihrem Fall ebenfalls problematisch.

Ich würde eines von zwei Dingen empfehlen.

  1. Suchen Sie nicht im Stammverzeichnis, sondern nur an den Orten, die möglicherweise nützlich sind. Suchen /homeoder /usroder /etcgetrennt. Die Informationen, nach denen Sie suchen, sind wahrscheinlich von einem bestimmten Typ, sodass sie sich wahrscheinlich sowieso in einem bestimmten Ordner befinden. Konfigurationseinstellungen sollten in sein /etc. Ihre persönlichen Daten sollten sich in befinden /home. Wenn Sie die Suche auf einen wichtigen Bereich wie diesen beschränken, werden Ihre Probleme mit rekursiven Greps erheblich reduziert.

  2. Schließen Sie problematische Bereiche mit --exclude-dirund einer Reihe von Dingen aus, von denen Sie wissen, dass Sie sie nicht benötigen:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Schließlich ist es nicht ungewöhnlich, dass bei einem großen rekursiven Grep einige Fehler auftreten, denen die Berechtigung verweigert wurde. Im normalen Nutzungsverlauf gibt es Dateien, die Ihr Benutzer möglicherweise nicht lesen kann. Solange es sich nur um einige ungerade Dateien handelt und nicht um Dinge wie das Raw-Gerät für Ihre Festplatten oder das gesamte Proc-Dateisystem, ist es in Ordnung, die Fehler einfach zu ignorieren. Tatsächlich können Sie dies in der Befehlszeile tun, indem Sie alle Fehler in never never land senden:

grep -r search_string /path 2> /dev/null
Caleb
quelle
3
-Ibinäre auszuschließen
Rahul Patil
2

Der Einfachheit halber würde ich ack-grep vorschlagen . Link zeigt in vielen Fällen, wann ack-grepeine bessere Option ist.

Zu verwenden ist nach der Installation:

ack-grep pattern /
bbaja42
quelle
Vielen Dank, dass Sie dies empfohlen haben, aber ich habe es ausgeführt und es hat mir nicht wirklich die erwarteten Suchergebnisse geliefert. Scheint, als müsste ich viele Einstellungen anpassen, um das zu bekommen, was ich will. Ab sofort funktioniert Richards Antwort sofort. Wir werden uns dies in Zukunft ansehen, da es auch nützlich erscheint.
Level1Coder
1

Eine andere Sichtweise ist die folgende:

grep -r /* | grep "800x600"
maniat1k
quelle
0

* dann bekomme ich einen / proc / sysrq-Trigger: Input / Output-Fehler

Ihr Befehl funktioniert. Sie erhalten diesen Fehler, weil Sie versuchen, laufende Prozesse nach einer Zeichenfolge zu durchsuchen.

Ich empfehle, Systemverzeichnisse mit auszuschließen

grep -exclude-dir = {proc, sys} "800x600" /

Koffee
quelle
-3

einfach richtig

grep -r "800x600" /

- Was in Ihrem aktuellen Befehl nicht stimmt, sind die Anführungszeichen "". Setzen Sie das Zeichenfolgenargument immer grepin Anführungszeichen.

Amita
quelle
3
Das ist hier nicht das Problem. Sie brauchen keine Anführungszeichen, wenn Sie diese Art von Argument angeben grep. Probieren Sie es aus und Sie werden sehen. Geben Sie die Zeichenfolge "800x600" in eine Datei ein, grep 800x600 fileund Sie werden sehen, dass sie einwandfrei funktioniert. Das OP hat offensichtlich ein anderes Problem.
SLM