Saya sering menggunakan find
perintah untuk mencari melalui kode sumber, menghapus file, apa pun. Anehnya, karena Subversion menyimpan duplikat dari setiap file di .svn/text-base/
direktori -nya, pencarian sederhana saya akhirnya mendapatkan banyak hasil duplikat. Sebagai contoh, saya ingin mencari uint
secara berulang dalam beberapa file messages.h
dan 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;
Bagaimana saya bisa mengatakan find
untuk mengabaikan .svn
direktori?
Pembaruan : Jika Anda memutakhirkan klien SVN Anda ke versi 1.7 ini tidak lagi menjadi masalah.
Fitur utama dari perubahan yang diperkenalkan pada Subversion 1.7 adalah sentralisasi penyimpanan metadata copy pekerjaan ke satu lokasi. Alih-alih
.svn
direktori di setiap direktori dalam copy pekerjaan, Subversion 1.7 copy pekerjaan hanya memiliki satu.svn
direktori — di root copy pekerjaan. Direktori ini termasuk (antara lain) database yang didukung SQLite yang berisi semua metadata yang dibutuhkan Subversion untuk copy pekerjaan itu.
-exec
dengan +
tidak garpu grep
untuk setiap file, saat menggunakannya dengan ;
tidak. Menggunakan -exec
sebenarnya lebih benar daripada menggunakan xargs
. Harap perhatikan bahwa perintah seperti ls
melakukan sesuatu bahkan jika daftar argumen kosong, sementara perintah seperti chmod
memberikan kesalahan jika ada argumen yang tidak mencukupi. Untuk melihat apa yang saya maksud, hanya mencoba perintah berikut di direktori yang tidak memiliki shell script: find /path/to/dir -name '*.sh' -print0 | xargs -0 chmod 755
. Bandingkan dengan yang satu ini: find /path/to/dir -name '*.sh' -exec chmod 755 '{}' '+'
.
grep
keluar .svn
juga bukan ide yang bagus. Sementara find
khusus untuk menangani file properti, grep
tidak. Dalam contoh Anda, file bernama '.svn.txt' juga akan difilter oleh egrep
perintah Anda . Meskipun Anda dapat memodifikasi regex Anda menjadi '^ / \. Svn $' , itu masih bukan praktik yang baik untuk melakukannya. The -prune
predikat find
karya sempurna untuk menyaring file (oleh nama file, atau penciptaan timestamp, atau kondisi apa pun yang Anda disediakan). Ini seperti bahkan jika Anda dapat membunuh seekor kecoa menggunakan pedang besar tidak berarti itu adalah cara yang disarankan untuk melakukannya :-).
find ... -print0 | xargs -0 egrep ...
sebagai gantinyafind ... -exec grep ...
(tidak bercabanggrep
untuk setiap file, tetapi untuk banyak file sekaligus). Dengan menggunakan formulir ini, Anda juga dapat memangkas.svn
direktori tanpa menggunakan-prune
opsi find, yaitufind ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...