Ich weiß, dass dies ein alter Thread ist, aber ich bin darauf gestoßen und dachte, ich würde meine Methode teilen, die sich als sehr schnelle Methode herausgestellt hat find
, um nur nicht-binäre Dateien zu finden:
find . -type f -exec grep -Iq . {} \; -print
Die -I
Option zu grep weist es an, Binärdateien sofort zu ignorieren, und die .
Option zusammen mit -q
macht es, dass es sofort mit Textdateien übereinstimmt, so dass es sehr schnell geht. Sie können das -print
in a -print0
für Rohrleitungen in ein xargs -0
oder etwas ändern , wenn Sie sich Gedanken über Leerzeichen machen (danke für den Tipp, @ lucas.werkmeister!)
Der erste Punkt ist auch nur für bestimmte BSD-Versionen find
wie z. B. unter OS X erforderlich , aber es schadet nichts, wenn Sie ihn immer dort haben, wenn Sie ihn in einen Alias oder etwas anderes einfügen möchten.
EDIT : Wie @ruslan richtig ausgeführt hat, der -and
kann verzichtet werden , da es impliziert.
find . -type f -exec grep -Il "" {} \;
.find -type f -exec grep -Iq . {} \; -and -print
was den Vorteil hat, dass es die Dateien in behältfind
; Sie können-print
durch eine andere ersetzen-exec
, die nur für Textdateien ausgeführt wird. (Wenn Siegrep
die Dateinamen drucken lassen , können Sie Dateinamen nicht mit Zeilenumbrüchen unterscheiden.)find . -type f -exec grep -Il . {} +
ist viel schneller. Nachteil ist, dass es nicht von einem anderen erweitert werden kann,-exec
wie @ lucas.werkmeister vorgeschlagen hatBasierend auf dieser SO-Frage :
grep -rIl "needle text" my_folder
quelle
-I
ist ein Lebensretter.Warum ist es unhandlich? Wenn Sie es häufig verwenden müssen und es nicht jedes Mal eingeben möchten, definieren Sie einfach eine Bash-Funktion dafür:
lege es in dein
.bashrc
und renne dann einfach:wann immer du willst.
BEARBEITEN , um die Bearbeitung von OP widerzuspiegeln:
Wenn Sie MIME-Informationen ausschneiden möchten, können Sie der Pipeline einfach eine weitere Stufe hinzufügen, in der MIME-Informationen herausgefiltert werden. Dies sollte es tun, indem sie nur das, was kommt vor
:
:cut -d':' -f1
:quelle
file
Handbuch: "Benutzer müssen wissen, dass auf allen lesbaren Dateien in einem Verzeichnis das Wort 'Text' gedruckt ist."/proc/meminfo
,/proc/cpuinfo
Usw. sind Textdateien, aberfile /proc/meminfo
sagt/proc/meminfo: empty
. Ich frage mich, ob "leer" zusätzlich zu "Text" getestet werden sollte, bin mir aber nicht sicher, ob auch andere Typen "leer" melden könnten.Dies ist leider nicht platzsparend. Das Einfügen in ein Bash-Skript macht es ein bisschen einfacher.
Das ist platzsparend:
quelle
text.bin
? 2. Was ist, wenn ein Dateiname a enthält:
?Ein anderer Weg, dies zu tun:
Wenn Sie auch leere Dateien möchten:
quelle
Wie wäre es damit:
Wenn Sie die Dateinamen ohne Dateityp verwenden möchten, fügen Sie einfach einen endgültigen
sed
Filter hinzu.Sie können nicht benötigte Dateitypen herausfiltern, indem Sie
-e 'type'
dem letztengrep
Befehl weitere Optionen hinzufügen .BEARBEITEN:
Wenn Ihre
xargs
Version diese-d
Option unterstützt , werden die obigen Befehle einfacher:quelle
So habe ich es gemacht ...
1. Erstellen Sie ein kleines Skript, um zu testen, ob eine Datei Klartext ist.
2. benutze find wie vorher
quelle
== *"text"* ]]
?Ich habe zwei Probleme mit der Antwort von histumness:
Es werden nur Textdateien aufgelistet. Sie werden nicht wie gewünscht durchsucht. Verwenden Sie, um tatsächlich zu suchen
Es erzeugt einen Grep-Prozess für jede Datei, der sehr langsam ist. Eine bessere Lösung ist dann
oder einfach
Dies dauert nur 0,2 Sekunden im Vergleich zu 4 Sekunden für die obige Lösung (2,5 GB Daten / 7700 Dateien), dh 20- mal schneller .
Auch niemand zitierte ag, den Silver Searcher oder ack-grep als Alternativen. Wenn eine davon verfügbar ist, sind sie viel bessere Alternativen:
Achten Sie als letzte Anmerkung auf Fehlalarme (Binärdateien als Textdateien). Ich hatte bereits falsch positiv mit grep / ag / ack, also liste die übereinstimmenden Dateien besser zuerst auf, bevor du die Dateien bearbeitest.
quelle
Obwohl es sich um eine alte Frage handelt, denke ich, dass dieser Infobild die Qualität der Antworten hier verbessern wird.
Wenn ich Dateien mit gesetztem ausführbaren Bit ignoriere , verwende ich einfach diesen Befehl:
Um zu verhindern, dass es rekursiv in andere Verzeichnisse eingegeben wird:
Keine Notwendigkeit für Rohre viele Befehle, nur den mächtigen Ebene zu mischen find Befehl.
Trotzdem hoffe ich, dass dies für jeden nützlich ist.
quelle
Ich mache es so: 1) Da es zu viele Dateien (~ 30k) gibt, um sie zu durchsuchen, generiere ich täglich die Textdateiliste für die Verwendung über crontab mit dem folgenden Befehl:
2) Erstellen Sie eine Funktion in .bashrc:
Dann kann ich den folgenden Befehl verwenden, um die Suche durchzuführen:
HTH :)
quelle
Ich bevorzuge Xargs
Wenn Ihre Dateinamen seltsam sind, suchen Sie mit den Optionen -0 nach:
quelle
grep eth0 $ (find / etc / -type f -exec Datei {} \; | egrep -i "text | ascii" | cut -d ':' -f1)
quelle
Hier ist eine vereinfachte Version mit erweiterten Erklärungen für Anfänger wie mich, die lernen möchten, wie man mehr als einen Befehl in eine Zeile setzt.
Wenn Sie das Problem schrittweise aufschreiben würden, würde es folgendermaßen aussehen:
Um dies zu erreichen, können wir drei UNIX - Befehle zur Verfügung :
find
,file
, undgrep
.find
überprüft jede Datei im Verzeichnis.file
wird uns den Dateityp geben. In unserem Fall suchen wir nach einer Rückgabe von 'ASCII-Text'grep
sucht in der Ausgabe von nach dem Schlüsselwort 'ASCII'file
Wie können wir diese also in einer einzigen Zeile aneinander reihen? Es gibt mehrere Möglichkeiten, dies zu tun, aber ich finde, dass es am sinnvollsten ist, dies in der Reihenfolge unseres Pseudocodes zu tun (insbesondere für Anfänger wie mich).
find ./ -exec file {} ";" | grep 'ASCII'
Sieht kompliziert aus, ist aber nicht schlecht, wenn wir es aufschlüsseln:
find ./
= Durchsuche jede Datei in diesem Verzeichnis. Derfind
Befehl druckt den Dateinamen einer Datei aus, die dem 'Ausdruck' entspricht, oder was auch immer nach dem Pfad steht, in unserem Fall das aktuelle Verzeichnis oder./
Das Wichtigste zu verstehen ist, dass alles nach diesem ersten Bit entweder als wahr oder falsch bewertet wird. Wenn True, wird der Dateiname ausgedruckt. Wenn nicht, wird der Befehl fortgesetzt.
-exec
= Dieses Flag ist eine Option innerhalb des Befehls find, mit der wir das Ergebnis eines anderen Befehls als Suchausdruck verwenden können. Es ist wie das Aufrufen einer Funktion innerhalb einer Funktion.file {}
= der Befehl, der innerhalb von aufgerufen wirdfind
. Derfile
Befehl gibt eine Zeichenfolge zurück, die den Dateityp einer Datei angibt. Regelmäßig würde es so aussehen :file mytextfile.txt
. In unserem Fall möchten wir, dass die Datei verwendet wird, die vomfind
Befehl angezeigt wird. Daher setzen wir die geschweiften Klammern ein{}
, um als leere Variable oder Parameter zu fungieren. Mit anderen Worten, wir fordern das System lediglich auf, für jede Datei im Verzeichnis eine Zeichenfolge auszugeben.";"
= Dies wird vonfind
und ist das Interpunktionszeichen am Ende unseres-exec
Befehls. Weitere Informationen finden Sie im Handbuch für 'Suchen', wenn Sie es benötigen, indem Sie es ausführenman find
.| grep 'ASCII'
=|
ist eine Pfeife. Pipe nimmt die Ausgabe von allem, was links ist, und verwendet sie als Eingabe für alles, was rechts ist. Es nimmt die Ausgabe desfind
Befehls (eine Zeichenfolge, die der Dateityp einer einzelnen Datei ist) und testet sie, um festzustellen, ob sie die Zeichenfolge enthält'ASCII'
. Wenn dies der Fall ist, wird true zurückgegeben.JETZT gibt der Ausdruck rechts von
find ./
true zurück, wenn dergrep
Befehl true zurückgibt. Voila.quelle
Wenn Sie daran interessiert sind, einen Dateityp anhand seiner magischen Bytes mithilfe des fantastischen
file
Dienstprogramms in Kombination mit der Leistung von zu findenfind
, kann dies nützlich sein:Ausgabe:
Legende:
$
ist die interaktive Shell-Eingabeaufforderung, in die wir unsere Befehle eingebenSie können das Teil nachträglich ändern
&&
, um ein anderes Skript aufzurufen oder andere Dinge inline auszuführen. Wenn diese Datei eine bestimmte Zeichenfolge enthält, können Sie die gesamte Datei katzen oder nach einer sekundären Zeichenfolge suchen.Erläuterung:
find
Elemente, die Dateien sindxargs
sicher, dass jedes Element als Zeile in einen Liner-bash
Befehl / ein Skript eingefügt wirdfile
Überprüft den Dateityp anhand eines magischen Bytes undgrep
prüft, ob ASCII vorhanden ist. Wenn ja, wird&&
der nächste Befehl ausgeführt.find
Druckt die Ergebnissenull
getrennt. Dies ist gut, um Dateinamen mit Leerzeichen und Metazeichen zu umgehen.xargs
Mit der-0
Option werden sienull
getrennt gelesen ,-I @@
jeder Datensatz wird verwendet und als Positionsparameter / Argument für das Bash-Skript verwendet.--
forbash
stellt sicher, dass alles, was danach kommt, ein Argument ist, auch wenn es mit-
like beginnt,-c
das sonst als Bash-Option interpretiert werden könnteWenn Sie andere Typen als ASCII suchen müssen, ersetzen Sie sie einfach durch einen
grep ASCII
anderen Typ, zgrep "PDF document, version 1.4"
quelle
Verwenden Sie den Befehl find, um alle Dateien aufzulisten, verwenden Sie den Befehl file, um zu überprüfen, ob es sich um Text handelt (nicht tar, key), und verwenden Sie schließlich den Befehl awk, um das Ergebnis zu filtern und zu drucken.
quelle
Wie wäre es damit
quelle
"needle text"
"needl text"
"needle text"
sie gefunden