Uso spesso il find
comando per cercare nel codice sorgente, eliminare i file, qualunque cosa. Stranamente, poiché Subversion memorizza i duplicati di ogni file nelle sue .svn/text-base/
directory, le mie semplici ricerche finiscono per ottenere molti risultati duplicati. Ad esempio, voglio cercare ricorsivamente uint
in più messages.h
e messages.cpp
file:
# 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;
Come posso dire find
di ignorare le .svn
directory?
Aggiornamento : se aggiorni il tuo client SVN alla versione 1.7 questo non è più un problema.
Una caratteristica chiave delle modifiche introdotte in Subversion 1.7 è la centralizzazione dell'archiviazione dei metadati di copia funzionante in un'unica posizione. Invece di una
.svn
directory in ogni directory nella copia di lavoro, le copie di lavoro di Subversion 1.7 hanno solo una.svn
directory nella radice della copia di lavoro. Questa directory include (tra le altre cose) un database supportato da SQLite che contiene tutti i metadati necessari a Subversion per quella copia di lavoro.
-exec
with +
non fa fork grep
per ogni file, mentre lo usa con ;
does. L'uso -exec
è in realtà più corretto dell'uso xargs
. Si noti che comandi come ls
fanno qualcosa anche se l'elenco degli argomenti è vuoto, mentre comandi come chmod
danno un errore se non ci sono argomenti sufficienti. Per capire cosa intendo, basta provare il seguente comando in una directory che non ha alcuna script di shell: find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755
. Confrontare con questo: find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'
.
grep
uscire .svn
non è una buona idea. Mentre find
è specializzato per la gestione delle proprietà dei file, grep
non lo è. Nel tuo esempio, anche un file chiamato ".svn.txt" verrà filtrato dal tuo egrep
comando. Sebbene sia possibile modificare il regex in '^ / \. Svn $' , non è comunque una buona pratica farlo. Il -prune
predicato di find
funziona perfettamente per filtrare un file (per nome file, timestamp di creazione o qualunque condizione fornita). È come se anche tu potessi uccidere uno scarafaggio usando una grande spada non significa che sia il modo suggerito per farlo :-).
find ... -print0 | xargs -0 egrep ...
invece difind ... -exec grep ...
(non forkgrep
per ogni file, ma per un mucchio di file alla volta). Usando questo modulo puoi anche eliminare le.svn
directory senza usare l'-prune
opzione find, ovverofind ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...