私はよく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
、作業コピーのルートに1つのディレクトリしかありません。このディレクトリには、(とりわけ)SQLiteでバックアップされたデータベースが含まれています。このデータベースには、その作業コピーにSubversionが必要とするすべてのメタデータが含まれています。
-exec
with を使用し+
てもgrep
各ファイルにfork しませんが、with を使用すると、fork します;
。を使用する方-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
アウト-ingが.svn
あまりにも良いアイデアではありません。一方でfind
、ファイルのプロパティを処理するために特化されて、grep
しません。この例では、「。svn.txt」という名前のファイルもegrep
コマンドによってフィルタリングされます。正規表現を'^ / \。svn $'に変更することはできますが、そうすることはまだお勧めできません。の-prune
述語はfind
、ファイルのフィルタリングに完全に機能します(ファイル名、作成タイムスタンプ、または指定した条件による)。たとえ大きな剣を使ってゴキブリを殺すことができたとしても、それがそうするための提案された方法であるとは限りません:-)。
find ... -print0 | xargs -0 egrep ...
に、代わりにを使用してみてくださいfind ... -exec grep ...
(grep
ファイルごとにfork するのではなく、一度に多数のファイルに対してfork します)。また、プルーンのことができます。このフォームを使用して.svn
使用せずにディレクトリを-prune
、すなわち、検索のオプションをfind ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...