Я часто использую findкоманду для поиска по исходному коду, удаления файлов, чего угодно. Досадно, потому что Subversion хранит дубликаты каждого файла в своих .svn/text-base/каталогах, мои простые поиски заканчиваются тем, что они получают много повторяющихся результатов. Например, я хочу , чтобы рекурсивно искать uintв многократном messages.hи 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;
Как я могу сказать, findчтобы игнорировать .svnкаталоги?
Обновление : если вы обновляете свой клиент SVN до версии 1.7, это больше не проблема.
Ключевой особенностью изменений, внесенных в Subversion 1.7, является централизация хранилища метаданных рабочей копии в одном месте. Вместо
.svnкаталога в каждом каталоге в рабочей копии рабочие копии Subversion 1.7 имеют только один.svnкаталог - в корне рабочей копии. Этот каталог включает (среди прочего) базу данных на основе SQLite, которая содержит все метаданные, необходимые Subversion для этой рабочей копии.
-execwith +не разветвляется grepдля каждого файла, в то время как использование with ;делает. Использование -execна самом деле более правильно, чем использование xargs. Обратите внимание, что такие команды как lsчто-то делают, даже если список аргументов пуст, в то время как такие команды chmodдают ошибку, если аргументов недостаточно. Для того, чтобы увидеть , что я имею в виду, просто попробуйте следующую команду в каталоге , который не имеет какой - либо скрипт: find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755. Сравните с этим: find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'.
grepвыход .svnтоже не очень хорошая идея. Пока findспециализируется на обработке свойств файла, grepнет. В вашем примере файл с именем '.svn.txt' также будет отфильтрован вашей egrepкомандой. Хотя вы можете изменить свое регулярное выражение на «^ / \. Svn $» , это все же не очень хорошая практика. -pruneПредикат findотлично работает для фильтрации файлов (по имени файла, или создания временной метки, или независимо от состояния вы прилагается). Это похоже на то, что даже если вы можете убить таракана с помощью большого меча, это не значит, что это рекомендуемый способ сделать это :-).
find ... -print0 | xargs -0 egrep ...вместоfind ... -exec grep ...(неgrepдля каждого файла, но для нескольких файлов одновременно). С помощью этой формы вы также можете обрезать.svnкаталоги, не используя-pruneопцию find, т.е.find ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...