J'utilise souvent la find
commande pour rechercher dans le code source, supprimer des fichiers, peu importe. Chose ennuyeuse, parce que Subversion stocke des doublons de chaque fichier dans ses .svn/text-base/
répertoires, mes recherches simples finissent par obtenir de nombreux résultats en double. Par exemple, je veux rechercher récursivement uint
dans plusieurs fichiers messages.h
et messages.cpp
:
# 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;
Comment puis-je dire find
d'ignorer les .svn
répertoires?
Mise à jour : si vous mettez à niveau votre client SVN vers la version 1.7, ce n'est plus un problème.
Une caractéristique clé des changements introduits dans Subversion 1.7 est la centralisation du stockage des métadonnées de copie de travail en un seul emplacement. Au lieu d'un
.svn
répertoire dans chaque répertoire de la copie de travail, les copies de travail de Subversion 1.7 n'ont qu'un seul.svn
répertoire, à la racine de la copie de travail. Ce répertoire comprend (entre autres) une base de données SQLite-soutenue qui contient tous les besoins de Subversion de métadonnées pour cette copie de travail.
-exec
avec +
ne se bifurque pas grep
pour chaque fichier, tout en l'utilisant avec le ;
fait. L'utilisation -exec
est en fait plus correcte que l'utilisation xargs
. Veuillez noter que les commandes comme ls
font quelque chose même si la liste des arguments est vide, tandis que les commandes comme chmod
donnent une erreur s'il n'y a pas suffisamment d'arguments. Pour voir ce que je veux dire, essayez la commande suivante dans un répertoire qui n'a pas de script shell: find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755
. Comparer avec celui - ci: find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'
.
grep
sortir .svn
n'est pas une bonne idée non plus. Bien qu'il find
soit spécialisé dans la gestion des propriétés des fichiers, il grep
ne l'est pas. Dans votre exemple, un fichier nommé '.svn.txt' sera également filtré par votre egrep
commande. Bien que vous puissiez modifier votre expression régulière en '^ / \. Svn $' , ce n'est toujours pas une bonne pratique de le faire. Le -prune
prédicat de find
fonctionne parfaitement pour filtrer un fichier (par nom de fichier, ou horodatage de création, ou quelle que soit la condition que vous avez fournie). C'est comme si même si vous pouvez tuer un cafard à l'aide d'une grosse épée, cela ne signifie pas que c'est la façon suggérée de le faire :-).
find ... -print0 | xargs -0 egrep ...
place defind ... -exec grep ...
(ne se bifurque pasgrep
pour chaque fichier, mais pour un tas de fichiers à la fois). En utilisant ce formulaire, vous pouvez également élaguer les.svn
répertoires sans utiliser l'-prune
option de recherche, c'estfind ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...