Często używam findpolecenia do przeszukiwania kodu źródłowego, usuwania plików, cokolwiek. Irytujące, ponieważ Subversion przechowuje duplikaty każdego pliku w swoich .svn/text-base/katalogach, moje proste wyszukiwania kończą się uzyskaniem wielu duplikatów wyników. Na przykład, chcę rekursywnie szukać uintw wielokrotności messages.hi messages.cppplików:
# 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;
Jak mogę findzignorować .svnkatalogi?
Aktualizacja : jeśli uaktualnisz swojego klienta SVN do wersji 1.7, nie będzie to już problemem.
Kluczową cechą zmian wprowadzonych w Subversion 1.7 jest centralizacja przechowywania metadanych kopii roboczej w jednym miejscu. Zamiast
.svnkatalogu w każdym katalogu w kopii roboczej, kopie robocze Subversion 1.7 mają tylko jeden.svnkatalog - w katalogu głównym kopii roboczej. Ten katalog zawiera (między innymi) bazę danych opartą na SQLite, która zawiera wszystkie potrzebne metadane Subversion dla tej kopii roboczej.
-execz +nie rozwidla grepdla każdego pliku, podczas gdy używanie z ;robi. Używanie -execjest właściwie bardziej poprawne niż używanie xargs. Zauważ, że polecenia takie jak lscoś robią, nawet jeśli lista argumentów jest pusta, podczas gdy polecenia takie chmoddają błąd, jeśli nie ma wystarczających argumentów. Aby zobaczyć, co mam na myśli, po prostu spróbuj następującą komendę w katalogu, który nie ma żadnego skrypt: find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755. Porównaj z tego: find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'.
greprezygnacja .svnnie jest dobrym pomysłem. Chociaż findjest wyspecjalizowany w obsłudze właściwości plików, grepnie robi tego. W twoim przykładzie plik o nazwie „.svn.txt” również zostanie odfiltrowany przez twoje egreppolecenie. Chociaż możesz zmodyfikować wyrażenie regularne na „^ / \. Svn $” , nadal nie jest to dobrą praktyką. -pruneOrzecznik finddziała idealnie do filtrowania plików (według nazwy pliku lub tworzenia datownik, czy cokolwiek warunek ty zestawie). To tak, jakby nawet jeśli możesz zabić karalucha za pomocą dużego miecza, nie oznacza to, że jest to sugerowany sposób :-).
find ... -print0 | xargs -0 egrep ...zamiastfind ... -exec grep ...(nie rozwidla sięgrepdla każdego pliku, ale dla kilku plików jednocześnie). Za pomocą tego formularza można również przycinać.svnkatalogi bez korzystania z-pruneopcji find, tj.find ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...