Ich möchte in allen Dateien eines Verzeichnisses (und nicht in seinen Unterverzeichnissen) nach einer Textzeichenfolge suchen. Ich weiß, dass die -r
Option dies tut, aber das ist nicht das, was ich will.
Laufen
grep "string" /path/to/dir
soll das können, habe ich gelesen, aber es gibt mir den fehler:
grep: dir: Ist ein Verzeichnis
Als nächstes habe ich versucht,
grep
mehrere Dateien auszuführen.grep "string" .bashrc .bash_aliases
funktioniert perfekt.grep "string" .bash*
funktioniert auch wie vorgesehen.grep "string" *
gibt mir die fehler:grep: data: Is a directory grep: Desktop: Is a directory grep: Documents: Is a directory grep: Downloads: Is a directory ...
Es werden nur die Fehler gedruckt, die übereinstimmenden Zeilen werden nicht angezeigt. Ich habe versucht, die -s
Option zu verwenden, aber ohne Erfolg.
Also meine Fragen:
Warum kann ich
grep
ein Verzeichnis nicht wie in (1) verwenden, wenn ich das sollte? Ich habe das an vielen Beispielen im Internet gesehen.
Bearbeiten : Wenn ich "grep für ein Verzeichnis verwenden" sage, meine ich "in allen Dateien in diesem Verzeichnis mit Ausnahme der Unterverzeichnisse suchen". Ich glaube, dass dies das ist, was grep tut, wenn Sie ein Verzeichnis anstelle einer Datei übergeben. Irre ich michBitte erläutern Sie mir die Funktionsweise
grep
, die das Verhalten der Befehle in (2) erklären würde.
Bearbeiten : Lassen Sie mich genauer sein. Warum funktioniert die Verwendung von Platzhaltern, um mehrere Dateien anzugeben, in denen nach gesucht werden soll,.bash*
und nicht mit*
oder sogar./*
?Wie kann ich alle Dateien in einem Verzeichnis (und nicht in dessen Unterverzeichnissen) durchsuchen
grep
?
*
Globbing" erweitert. Beim Globbing werden keine Dateinamen berücksichtigt, die mit einem Punkt wie.bashrc
dem Standard beginnen. Sie können die Shell-Optionen so einstellen, dass sie diese Dateien enthalten, aber Sie können sich selbst ein bisschen durcheinander bringen, wenn Sie nicht wissen, was Sie tun. Eine gute Anleitung zum Verständnis des Globierens finden Sie hier mywiki.wooledge.org/globgrep "string" .bash*
.grep "string" * .* 2>/dev/null
odergrep -s "string" * .*
Antworten:
In Bash wird ein Glob nicht in versteckte Dateien expandiert. Wenn Sie also alle Dateien in einem Verzeichnis durchsuchen möchten , müssen Sie versteckte
.*
und nicht versteckte Dateien angeben*
.Um die "Ist ein Verzeichnis" -Fehler zu vermeiden, könnten Sie verwenden
-d skip
, aber auf meinem System erhalte ich auch einen Fehlergrep: .gvfs: Permission denied
† , daher empfehle ich die Verwendung-s
, bei der alle Fehlermeldungen ausgeblendet werden.Der gesuchte Befehl lautet also:
Wenn Sie Dateien in einem anderen Verzeichnis suchen:
Eine weitere Option ist die Verwendung der
dotglob
Shell-Option, mit der ein Glob versteckte Dateien einbezieht.Für Dateien in einem anderen Verzeichnis:
† Jemand erwähnte, dass ich diesen Fehler nicht bekommen sollte. Sie mögen Recht haben - ich habe ein bisschen gelesen, aber ich konnte es mir nicht vorstellen.
quelle
*
und.*
?echo * .*
undecho *.*
führen Sie sie in Ihrem Home-Verzeichnis aus. Der Unterschied sollte offensichtlich sein. Ansonsten LMK und ich werde es erklären.echo *
zeigt also nicht versteckte Dateien und Ordner,echo *.*
zeigt nicht versteckte Dateien,echo .*
zeigt alle Dateien undecho * .*
zeigt alle Dateien und Verzeichnisse. Aber warum der Grund für den Abstand zwischen den beiden im letzteren Fall? Es fühlt sich für mich unordentlich an. Gibt es keine Möglichkeit, beide zu kombinieren, um die gleichen Ergebnisse zu erzielen? Oder gibt es sonst eine syntaktische Erklärung, warum die beiden hier getrennt werden müssen, oder handelt es sich um* .*
einen Ausnahmefall?*
alle nicht ausgeblendeten Dateien dar (dh Dateinamen, die nicht mit einem Punkt beginnen)..*
stellt alle versteckten Dateien dar (dh Dateinamen, die mit einem Punkt beginnen); und*.*
repräsentiert alle nicht ausgeblendeten Dateien, die einen Punkt enthalten . Inecho * .*
müssen die beiden Globs getrennt sein, da es sich um unterschiedliche Globs handelt: einer für nicht ausgeblendete und einer für ausgeblendete. Obwohl ich in meiner Antwort geschrieben habe, können Sie*
versteckte Dateien einschließen, indem Sie diedotglob
Shell-Option aktivieren.*.*
ist unter Windows (DOS) üblich, um alle Dateien aufzulisten. Unter * nix werden jedoch nur Dateien mit einem Punkt in die Liste aufgenommen, was unter * nix keinen Sinn ergibt. Stattdessen verwenden Sie,*
um alle Dateien außer versteckten Dateien aufzulisten und.*
versteckte Dateien aufzulisten.Sie müssen die
-d skip
Option hinzufügen.Grep sucht in Dateien. Sie können, wie Sie sagten, rekursiv suchen, wenn Sie Dateien in einem Verzeichnis suchen möchten.
Standardmäßig liest grep alle Dateien und erkennt die Verzeichnisse. Da Sie mit der
-d
Option standardmäßig nicht definiert haben, was mit den Verzeichnissen geschehen soll, wird eine Fehlerausgabe ausgegeben.Nur innerhalb des übergeordneten Verzeichnisses zu suchen, wäre `grep -d" string "überspringen ./*
quelle
man grep
.-d skip
funktioniert nicht; es ist im Grunde das gleiche wie-s
; siehe auch die Bearbeitung. (c) Nein,grep -d skip "string" ./*
funktioniert auch nicht.Oldtimer würden dies wahrscheinlich tun:
quelle
find . -type f -exec grep string {} +
?-maxdepth 1
.find . -type f -maxdepth 1 -exec grep string /dev/null {} +
-H
zu grep.Umformulierung - Sie möchten die Dateien in einer Ebene des Unterverzeichnisses speichern, aber nicht alle Unterverzeichnisse erneut durchsuchen?
Oder wenn Sie die Dateien nicht im aktuellen Verzeichnis haben möchten
Beachten Sie, dass Verzeichnisse, die mit einem Punkt beginnen, nicht gefunden werden.
sollte diesen Job machen.
Es gibt auch
-maxdepth
und-mindepth
Einschränkungsparameter für denfind
Befehl.quelle
grep forthis */*
Dateien sowohl im aktuellen als auch in einem darunter liegenden Verzeichnis zu suchen?*/*
nur einen Schrägstrich gibt. Wenn Siea/b
im aktuellen Verzeichnis eine Datei mit dem Namen * / * hätten, würde das passen.Hier ist ein Beispiel, um Verzeichnisse zu überspringen, ohne alle Fehler zu überspringen:
quelle