Я часто использую 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 для этой рабочей копии.
-exec
with +
не разветвляется 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 ...