我经常使用该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
为每个文件派生,而使用它;
会。使用-exec
实际上比使用更正确xargs
。请注意,ls
即使参数列表为空,诸如此类的命令也会执行某些操作;而chmod
如果参数不足,则此类命令会给出错误。要了解我的意思,只需在没有任何shell脚本的目录中尝试以下命令: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 ...