Wie kann man nach einem Dateinamen anstelle des Inhalts einer Datei suchen?

133

grep wird verwendet, um in einer Datei zu suchen, ob eine Zeile mit einem bestimmten regulären Ausdruck übereinstimmt. Ich habe jedoch diese Situation - ich möchte einen regulären Ausdruck schreiben, der mit dem Dateinamen selbst (und nicht mit dem Inhalt der Datei) übereinstimmt. Ich werde dies aus dem Stammverzeichnis des Systems ausführen, um alle Dateien zu finden, die dem regulären Ausdruck entsprechen.

Wenn ich beispielsweise alle VB-Formulardateien suchen möchte, die mit einem "f" beginnen und mit .frm enden, verwende ich den regulären Ausdruck -

   "f[[:alnum:]]*\.frm"

Kann grep das machen? Wenn nicht, gibt es ein Dienstprogramm, mit dem ich dies tun kann? Vielen Dank.

Code blau
quelle

Antworten:

119

Sie müssen findanstelle von grepin diesem Fall verwenden.

Sie können auch findin Kombination mit grepoder verwenden egrep:

$ find | grep "f[[:alnum:]]\.frm"
Pablo Santa Cruz
quelle
12
Dies ist nicht erforderlich. In Find ist diese Funktionalität mit der -regexOption integriert.
Whereswalden
4
Dies ist hier nicht erforderlich, aber grep unterstützt Perl-Regex, Find jedoch nicht.
Dan
2
Nein, Sie können grep verwenden. Viel einfacher als find. Fügen Sie den Schalter "-rl" hinzu und es wird der Dateiname anstelle der Datei durchsucht. Siehe meinen Beitrag unten.
RM
@ alpha_989, ich sagte, grep unterstützt es, was es tut: gnu.org/software/grep/manual/html_node/… point is piping to grep wird nur benötigt, wenn Sie pcre benötigen. Whereswalden hat die richtige Antwort
Dan
60

Beispiel

find <path> -name *FileName*

Aus dem Handbuch:

find-name pattern

Die Basis des Dateinamens (der Pfad mit den entfernten führenden Verzeichnissen) entspricht dem Shell-Mustermuster. Da die führenden Verzeichnisse entfernt werden, enthalten die Dateinamen, die für eine Übereinstimmung mit -name berücksichtigt werden, niemals einen Schrägstrich, sodass "-name a / b" niemals mit irgendetwas übereinstimmt (Sie müssen wahrscheinlich stattdessen -path verwenden). Die Metazeichen ("*", "?" Und "[]") stimmen mit einem "." am Anfang des Basisnamens (dies ist eine Änderung in find-utils-4.2.2; siehe Abschnitt STANDARDS CONFORMANCE unten). Verwenden Sie -prune, um ein Verzeichnis und die darunter liegenden Dateien zu ignorieren. Siehe ein Beispiel in der Beschreibung von -path. Zahnspangen werden nicht als besonders anerkannt, obwohl einige Muscheln, einschließlich Bash, Zahnspangen mit einer besonderen Bedeutung in Muschelmustern durchdringen. Der Dateinamenabgleich wird unter Verwendung der Bibliotheksfunktion fnmatch (3) durchgeführt. Vergessen Sie nicht, das Muster in Anführungszeichen zu setzen, um es vor einer Erweiterung durch die Shell zu schützen.

javaPlease42
quelle
2
Ich fand diese Antwort am nützlichsten. Ich habe ein paar zusätzliche Optionen hinzugefügt: find . -maxdepth 1 -name "*filename*" -print
JSON C11
47

Als Pablo sagte, müssen Sie verwenden findstatt grep, aber es gibt kein Bedürfnis, findzu grep. findhat diese Funktionalität eingebaut:

find . -regex 'f[[:alnum:]]\.frm'

findist ein sehr leistungsfähiges Programm zum Suchen nach Dateien nach Namen und unterstützt das Suchen nach Dateityp, Tiefenbegrenzung, Kombinieren verschiedener Suchbegriffe mit booleschen Operationen und Ausführen beliebiger Befehle für gefundene Dateien. Siehe die Fund Manpage für weitere Informationen.

Whereswalden
quelle
1
Ich würde die sehr praktische Funktion der Suche hinzufügen, um nach Datum mit -mtimeund-mmin
Johnride
1
Außerdem führt der Schalter -regex Übereinstimmungen mit dem gesamten Pfad durch. Um zu arbeiten, muss das Beispiel. * Am Anfang des regulären Ausdrucks hinzufügen.
Tumasgiu
15

Sie können den vollständigen Pfad einer Datei mit grep ermitteln. Leiten Sie einfach die Ausgabe des Baums weiter

tree -f | grep filename

Hier ist eine Funktion, die Sie in Ihr .bash_profile oder .bashrc einfügen können

findfile(){ tree -f | grep $1; } # $1 = filename, -f is full path
jasonleonhard
quelle
-f ist optional.
Jasonleonhard
10
find -iname "file_name"

Syntax :-
find -type type_descriptor file_name_here

type_descriptor types: -

f: reguläre Datei

d: Verzeichnis

l: symbolische Verbindung

c: Zeichengeräte

b: Geräte blockieren

Sireesh Yarlagadda
quelle
1
Ich kann anscheinend keinen Dateinamen verwenden, der dem -type typedescriptorallein folgt . Ist das ein Fehler?
Allan Nørgaard
5

Sie können auch tun:

tree | grep filename

Dadurch wird die Ausgabe des Befehls tree an grep weitergeleitet, um nach einer Suche zu suchen. Hier erfahren Sie jedoch nur, ob die Datei vorhanden ist.

Caylus
quelle
1

Nein, grep funktioniert gut dafür:

 grep -rl "filename" [starting point]

 grep -rL "not in filename"
RM
quelle
1
Dies durchsucht den Dateiinhalt nach "Dateiname" und druckt dann die Namen von Dateien mit Übereinstimmungen. OP möchte übereinstimmende Dateinamen, keine Dateiinhalte.
Matthew
1
Einverstanden, dies sucht nicht nach Dateinamen, sondern druckt nur die Namen der Dateinamen, für die der gefundene Inhalt übereinstimmt. Sie haben sowohl die -lals auch die -LOptionen erheblich missverstanden .
Prometheus
2
+1 für genau das, was ich brauche. Glücklich, dass ich die Frage nicht kritisieren musste, um die Antwort zu finden, die ich brauchte
Alexander McNulty
-1

Auch für mehrere Dateien.

tree /path/to/directory/ | grep -i "file1 \| file2 \| file3"
DimiDak
quelle
-1

Der einfachste Weg ist

find . | grep test

Hier finden find alle Dateien im (.) dh aktuellen Verzeichnis rekursiv. Und dann ist es nur ein einfacher Grep. Alle Dateien mit dem Namen "test" werden angezeigt.

Sie können mit Grep gemäß Ihren Anforderungen spielen. Hinweis: Da es sich bei grep um eine generische Zeichenfolgenklassifizierung handelt, können nicht nur Dateinamen angezeigt werden. Wenn ein Pfad jedoch ein Verzeichnis ('/xyz_test_123/other.txt') hat, wird auch die Ergebnismenge angezeigt. Prost

sachyy
quelle
Dies wird alles mit "Test" im Pfad finden, z ./foo/bar/latest/fred.txt.
Paul R
Oh. An diesen habe ich nicht gedacht. Vielen Dank für die Erwähnung.
Sachyy