Ich benutze den find
Befehl oft, um den Quellcode zu durchsuchen, Dateien zu löschen, was auch immer. Ärgerlicherweise, weil Subversion Duplikate jeder Datei in seinen .svn/text-base/
Verzeichnissen speichert, erhalten meine einfachen Suchvorgänge viele doppelte Ergebnisse. Zum Beispiel möchte ich rekursiv uint
in mehreren messages.h
und messages.cpp
Dateien suchen :
# find -name 'messages.*' -exec grep -Iw uint {} +
./messages.cpp: Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./messages.cpp: Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./messages.cpp: Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./messages.cpp: Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./messages.cpp: Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./messages.cpp: Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./messages.cpp: for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Discarding out of date message: id " << uint(olderMessage.id)
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Added to send queue: " << *message << ": id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base: Log::error << "Received message with invalid SHA-1 hash: id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Received " << *message << ": id " << uint(incomingMessage.id)
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Sent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base: Log::verbose << "Discarding unsent message: id " << uint(preparedMessage->id)
./.svn/text-base/messages.cpp.svn-base: for (uint i = 0; i < 10 && !_stopThreads; ++i) {
./virus/messages.cpp:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/messages.cpp:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/messages.h: void _progress(const std::string &fileName, uint scanCount);
./virus/messages.h: ProgressMessage(const std::string &fileName, uint scanCount);
./virus/messages.h: uint _scanCount;
./virus/.svn/text-base/messages.cpp.svn-base:void VsMessageProcessor::_progress(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.cpp.svn-base:ProgressMessage::ProgressMessage(const string &fileName, uint scanCount)
./virus/.svn/text-base/messages.h.svn-base: void _progress(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base: ProgressMessage(const std::string &fileName, uint scanCount);
./virus/.svn/text-base/messages.h.svn-base: uint _scanCount;
Wie kann ich sagen find
, dass die .svn
Verzeichnisse ignoriert werden sollen ?
Update : Wenn Sie Ihren SVN-Client auf Version 1.7 aktualisieren, ist dies kein Problem mehr.
Ein wesentliches Merkmal der in Subversion 1.7 eingeführten Änderungen ist die Zentralisierung des Speichers von Arbeitskopien-Metadaten an einem einzigen Speicherort. Anstelle eines
.svn
Verzeichnisses in jedem Verzeichnis in der Arbeitskopie haben Subversion 1.7-Arbeitskopien nur ein.svn
Verzeichnis - im Stammverzeichnis der Arbeitskopie. Dieses Verzeichnis enthält (unter anderem) eine SQLite-gestützte Datenbank, die alle Metadaten enthält, die Subversion für diese Arbeitskopie benötigt.
-exec
mit +
Gabel nicht grep
für jede Datei, während es bei der Verwendung des ;
Fall ist. Verwenden -exec
ist eigentlich korrekter als Verwenden xargs
. Bitte beachten Sie, dass Befehle wie " ls
etwas tun", auch wenn die Argumentliste leer ist, während Befehle wie " chmod
Fehler" geben, wenn nicht genügend Argumente vorhanden sind. Um zu sehen, was ich meine, versuchen Sie einfach den folgenden Befehl in einem Verzeichnis, das kein Shell-Skript enthält : find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755
. Vergleichen Sie mit diesem : find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'
.
grep
-ing out .svn
ist auch keine gute Idee. Während find
es auf die Behandlung von Dateieigenschaften spezialisiert ist, ist grep
dies nicht der Fall. In Ihrem Beispiel wird eine Datei mit dem Namen '.svn.txt' ebenfalls von Ihrem egrep
Befehl gefiltert . Obwohl Sie Ihren regulären Ausdruck in '^ / \. Svn $' ändern können , ist dies immer noch keine gute Vorgehensweise. Das -prune
Prädikat von find
eignet sich perfekt zum Filtern einer Datei (nach Dateiname, Erstellungszeitstempel oder der von Ihnen angegebenen Bedingung). Es ist so, als ob selbst wenn man eine Kakerlake mit einem großen Schwert töten kann, dies nicht bedeutet, dass dies der vorgeschlagene Weg ist :-).
find ... -print0 | xargs -0 egrep ...
anstelle von zu verwendenfind ... -exec grep ...
(nichtgrep
für jede Datei, sondern für mehrere Dateien gleichzeitig). Mit diesem Formular können Sie auch.svn
Verzeichnisse-prune
find ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...