ฉันมักจะใช้find
คำสั่งเพื่อค้นหาผ่านซอร์สโค้ดลบไฟล์อะไรก็ตาม น่ารำคาญเพราะการโค่นล้มเก็บข้อมูลที่ซ้ำกันของแต่ละไฟล์ใน.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จะไม่มีปัญหาอีกต่อไป
คุณสมบัติที่สำคัญของการเปลี่ยนแปลงที่นำมาใช้ในการโค่นล้ม 1.7 คือการรวมศูนย์ของที่เก็บข้อมูลเมทาดาทางานที่คัดลอกไว้ในที่เดียว แทนที่จะเป็น
.svn
ไดเรกทอรีในทุกไดเรกทอรีในสำเนาการทำงาน Subversion 1.7 สำเนาการทำงานมีเพียง.svn
ไดเรกทอรีเดียว- ในรากของสำเนาการทำงาน ไดเรกทอรีนี้รวมถึง (เหนือสิ่งอื่นใด) ฐานข้อมูล SQLite ที่สำรองไว้ซึ่งมีความต้องการการโค่นล้มข้อมูลเมตาทั้งหมดสำหรับสำเนาการทำงานนั้น
-exec
ด้วย+
ไม่แยกgrep
สำหรับแต่ละไฟล์ในขณะที่ใช้ด้วย;
ทำ ใช้-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
คำสั่งของคุณ แม้ว่าคุณสามารถปรับเปลี่ยน regex ของคุณเป็น'^ / \. svn $' ได้แต่ก็ยังไม่เป็นเช่นนั้น เพรดิเคต-prune
ของการfind
ทำงานอย่างสมบูรณ์แบบสำหรับการกรองไฟล์ (ตามชื่อไฟล์หรือเวลาการสร้างหรือเงื่อนไขใด ๆ ที่คุณให้ไว้) มันก็เหมือนกับแม้ว่าคุณจะสามารถฆ่าแมลงสาบด้วยดาบขนาดใหญ่ไม่ได้หมายความว่ามันเป็นวิธีที่แนะนำให้ทำ :-)
find ... -print0 | xargs -0 egrep ...
แทนfind ... -exec grep ...
(ไม่แยกgrep
กันสำหรับแต่ละไฟล์ แต่สำหรับแต่ละไฟล์ในเวลาเดียวกัน) ใช้แบบฟอร์มนี้คุณยังสามารถตัด.svn
ไดเรกทอรีโดยไม่ใช้-prune
ตัวเลือกของการค้นหาเช่นfind ... -print0 | egrep -v '/\.svn' | xargs -0 egrep ...