Các lựa chọn thay thế nhanh hơn để tìm thấy các điểm khác nhau


22

Tôi sẽ muốn sử dụng "tìm" và định vị "để tìm kiếm các tệp nguồn trong dự án của mình, nhưng chúng mất nhiều thời gian để chạy. Có những lựa chọn thay thế nhanh hơn cho các chương trình này mà tôi không biết hoặc cách để tăng tốc hiệu suất của những chương trình này?


2
locatenên đã nhanh chóng rất nhiều, vì nó sử dụng một chỉ mục được xây dựng sẵn (cảnh báo chính là nó cần được cập nhật), trong khi findphải đọc danh sách thư mục.
afrazier

2
Bạn đang sử dụng định vị nào? mlocate nhanh hơn slocate bằng một chặng đường dài (lưu ý rằng bất kỳ gói nào bạn đã cài đặt, lệnh vẫn được định vị, vì vậy hãy kiểm tra trình quản lý gói của bạn)
Paul

@benhsu, khi tôi chạy find /usr/src -name fprintf.ctrên máy tính để bàn OpenBSD của mình, nó sẽ trả về vị trí của các tệp nguồn đó trong vòng chưa đầy 10 giây. locate fprintf.c | grep '^/usr/src.*/fprintf.c$'trở lại dưới một giây. Định nghĩa của bạn về "thời gian dài để chạy" là gì và làm thế nào để bạn sử dụng findlocate?
Kusalananda

@Paul, mình đang dùng mlocate.
benhsu

@KAK, tôi muốn sử dụng đầu ra của find / location để mở tệp trong emacs. trường hợp sử dụng mà tôi có là, tôi muốn chỉnh sửa tệp, tôi nhập tên tệp (hoặc một số biểu thức khớp với tên tệp) vào emacs và emacs sẽ sử dụng find / định vị để hiển thị danh sách các tệp khớp với nó, vì vậy tôi sẽ thích thời gian phản hồi đủ nhanh để tương tác (dưới 1 giây). Tôi có khoảng 3 triệu tệp trong $ HOME, một điều tôi có thể làm là làm cho lệnh find của tôi cắt bớt một số tệp.
benhsu

Câu trả lời:


16

Tìm kiếm các tệp nguồn trong một dự án

Sử dụng một lệnh đơn giản hơn

Nói chung, nguồn cho một dự án có thể ở một nơi, có thể trong một vài thư mục con được lồng không quá hai hoặc ba sâu, vì vậy bạn có thể sử dụng lệnh (có thể) nhanh hơn như

(cd /path/to/project; ls *.c */*.c */*/*.c)

Sử dụng siêu dữ liệu dự án

Trong một dự án C, bạn thường có Makefile. Trong các dự án khác, bạn có thể có một cái gì đó tương tự. Đây có thể là một cách nhanh chóng để trích xuất danh sách các tệp (và vị trí của chúng) viết một tập lệnh sử dụng thông tin này để định vị tệp. Tôi có một tập lệnh "nguồn" để tôi có thể viết các lệnh như thế nào grep variable $(sources programname).

Tăng tốc tìm

Tìm kiếm ít nơi hơn, thay vì find / …sử dụng find /path/to/project …nếu có thể. Đơn giản hóa các tiêu chí lựa chọn càng nhiều càng tốt. Sử dụng đường ống để trì hoãn một số tiêu chí lựa chọn nếu điều đó hiệu quả hơn.

Ngoài ra, bạn có thể giới hạn độ sâu của tìm kiếm. Đối với tôi, điều này giúp cải thiện tốc độ 'tìm kiếm' rất nhiều. Bạn có thể sử dụng công tắc -maxdepth. Ví dụ '-maxdepth 5'

Tăng tốc xác định vị trí

Đảm bảo rằng nó đang lập chỉ mục các vị trí bạn quan tâm. Đọc trang hướng dẫn và sử dụng bất kỳ tùy chọn nào phù hợp với nhiệm vụ của bạn.

   -U <dir>
          Create slocate database starting at path <dir>.

   -d <path>
          --database=<path> Specifies the path of databases to search  in.


   -l <level>
          Security  level.   0  turns  security checks off. This will make
          searchs faster.   1  turns  security  checks  on.  This  is  the
          default.

Loại bỏ nhu cầu tìm kiếm

Có thể bạn đang tìm kiếm bởi vì bạn đã quên nơi nào đó hoặc không được nói. Trong trường hợp trước, viết ghi chú (tài liệu), trong trường hợp sau, hỏi? Các quy ước, tiêu chuẩn và tính nhất quán có thể giúp ích rất nhiều.


10

Tôi đã sử dụng phần "tăng tốc xác định vị trí" trong câu trả lời của RedGrittyBrick. Tôi đã tạo một db nhỏ hơn:

updatedb -o /home/benhsu/ben.db -U /home/benhsu/ -e "uninteresting/directory1 uninteresting/directory2"

rồi chỉ locatevào nó:locate -d /home/benhsu/ben.db


6

Một chiến thuật mà tôi sử dụng là áp dụng -maxdepthtùy chọn với find:

find -maxdepth 1 -iname "*target*"

Lặp lại với độ sâu tăng dần cho đến khi bạn tìm thấy những gì bạn đang tìm kiếm, hoặc bạn cảm thấy mệt mỏi khi tìm kiếm. Một vài lần lặp đầu tiên có khả năng quay lại ngay lập tức.

Điều này đảm bảo rằng bạn không lãng phí thời gian trước khi nhìn xuyên qua độ sâu của các cây con lớn khi những gì bạn đang tìm kiếm có nhiều khả năng ở gần cơ sở của hệ thống phân cấp.


Đây là một kịch bản ví dụ để tự động hóa quá trình này (Ctrl-C khi bạn thấy những gì bạn muốn):

(
TARGET="*target*"
for i in $(seq 1 9) ; do
   echo "=== search depth: $i"
   find -mindepth $i -maxdepth $i -iname "$TARGET"
done
echo "=== search depth: 10+"
find -mindepth 10 -iname $TARGET
)

Lưu ý rằng sự dư thừa vốn có liên quan (mỗi lần vượt qua sẽ phải duyệt qua các thư mục được xử lý trong các lần chuyển trước) sẽ được tối ưu hóa đi qua bộ nhớ đệm trên đĩa.

Tại sao không findcó thứ tự tìm kiếm này như một tính năng tích hợp? Có lẽ bởi vì nó sẽ phức tạp / không thể thực hiện nếu bạn cho rằng việc truyền tải dự phòng là không thể chấp nhận được. Sự tồn tại của các -depthtùy chọn gợi ý về khả năng, nhưng than ôi ...


1
... do đó thực hiện tìm kiếm "đầu tiên".
tộc

3

Một giải pháp dễ dàng khác là sử dụng toàn cầu vỏ mở rộng mới hơn. Để bật:

  • bash: shopt -s globalstar
  • ksh: set -o globalstar
  • zsh: đã được kích hoạt

Sau đó, bạn có thể chạy các lệnh như thế này trong thư mục nguồn cấp cao nhất:

# grep through all c files
grep printf **/*.c

# grep through all files
grep printf ** 2>/dev/null

Điều này có lợi thế là nó tìm kiếm đệ quy thông qua tất cả các thư mục con và rất nhanh.


3

Người tìm kiếm bạc

Bạn có thể thấy nó hữu ích cho việc tìm kiếm rất nhanh nội dung của một số lượng lớn các tệp mã nguồn. Chỉ cần gõ ag <keyword>. Đây là một số đầu ra của tôi apt show silversearcher-ag:

Tôi thường sử dụng nó với:

-G --file-search-regex PATTERN Chỉ tìm kiếm tập tin có tên phù hợp với MẪU.

ag -G "css$" important

ảnh chụp màn hình


1
các nhân ripgrep algorythm là bị cáo buộc nhanh hơn silversearch, và nó cũng vinh danh .gitignorecác tập tin và bỏ qua .git, .svn, .hg.. thư mục.
ccpizza

@ccpizza Vậy sao? Trình tìm kiếm bạc cũng vinh danh .gitignorevà bỏ qua các tệp ẩn và nhị phân theo mặc định. Cũng có nhiều người đóng góp hơn, nhiều ngôi sao hơn trên Github (14700 so với 8300) và đã có trên các bản phát hành của thị trưởng. Vui lòng cung cấp một so sánh nguồn bên thứ ba đáng tin cậy cập nhật. Tuy nhiên, ripgreptrông có vẻ là một phần mềm tuyệt vời.
Pablo A

thật tốt khi biết Tôi không liên kết với (các) tác giả ripgreptheo bất kỳ cách nào, nó chỉ phù hợp với yêu cầu của tôi nên tôi đã ngừng tìm kiếm các lựa chọn khác.
ccpizza

Người tìm kiếm bạc .gitignorecũng tôn trọng . Điều đó nói rằng, rglà hoàn toàn tuyệt vời. Trước hết, nó có hỗ trợ unicode. Theo kinh nghiệm của tôi rgliên tục nhanh nhất ít nhất gấp đôi ag(YMMV), tôi đoán đó là do trình phân tích cú pháp regex của Rust, điều đó rõ ràng chưa sẵn sàng trong những năm qua aglà mới. rgcó thể đưa ra kết quả xác định (nhưng không theo mặc định), nó có thể liệt kê các loại tệp trong danh sách đen, trong đó chỉ có thể liệt kê agdanh sách trắng, nó có thể bỏ qua các tệp dựa trên kích thước (tạm biệt nhật ký). Tôi vẫn sử dụng agtrong trường hợp tôi cần kết hợp nhiều dòng, điều này rgkhông thể làm được.
Pellmeister

2

Để tìm một sự thay thế, hãy kiểm tra fd . Nó có giao diện đơn giản / trực quan hơn so với lệnh find ban đầu và nhanh hơn một chút.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.