Costumo usar o find
comando para pesquisar no código fonte, excluir arquivos, o que for. Irritantemente, porque o Subversion armazena duplicatas de cada arquivo em seus .svn/text-base/
diretórios, minhas pesquisas simples acabam obtendo muitos resultados duplicados. Por exemplo, desejo pesquisar recursivamente uint
em vários arquivos messages.h
e 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;
Como posso dizer find
para ignorar os .svn
diretórios?
Atualização : se você atualizar o seu cliente SVN para a versão 1.7, isso não será mais um problema.
Um recurso importante das alterações introduzidas no Subversion 1.7 é a centralização do armazenamento de metadados da cópia de trabalho em um único local. Em vez de um
.svn
diretório em todos os diretórios da cópia de trabalho, as cópias de trabalho do Subversion 1.7 têm apenas um.svn
diretório - na raiz da cópia de trabalho. Este diretório inclui (entre outras coisas) um banco de dados baseado em SQLite que contém todos os metadados que o Subversion precisa para essa cópia de trabalho.
-exec
com +
não bifurca grep
para cada arquivo, enquanto usá-lo com ;
faz. Usar -exec
é realmente mais correto do que usar xargs
. Observe que comandos como ls
fazem algo mesmo que a lista de argumentos esteja vazia, enquanto comandos como chmod
dão um erro se houver argumentos insuficientes. Para ver o que quero dizer, tente o seguinte comando em um diretório que não tem qualquer script shell: find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755
. Compare com esta: find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'
.
grep
sair .svn
também não é uma boa ideia. Enquanto find
é especializado para manipular propriedades de arquivo, grep
não. No seu exemplo, um arquivo chamado '.svn.txt' também será filtrado pelo seu egrep
comando. Embora você possa modificar seu regex para '^ / \. Svn $' , ainda não é uma boa prática fazer isso. O -prune
predicado find
funciona perfeitamente para filtrar um arquivo (por nome de arquivo ou carimbo de data / hora da criação ou qualquer condição que você forneceu). É como se você pudesse matar uma barata usando uma espada grande, não significa que é a maneira sugerida de fazê-lo :-).
find ... -print0 | xargs -0 egrep ...
vez defind ... -exec grep ...
(não bifurcagrep
para cada arquivo, mas para vários arquivos por vez). Usando este formulário, você também pode remover.svn
diretórios sem usar a-prune
opção find, ou seja,find ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...