Làm thế nào để bắt đầu grep đa luồng trong thiết bị đầu cuối?


38

Tôi có một thư mục chứa hơn 250 tệp mỗi tệp. Tôi cần tìm kiếm một chuỗi / mẫu trong các tệp đó và xuất kết quả trong một outputtệp. Tôi biết tôi có thể chạy lệnh sau, nhưng quá chậm !!

grep mypattern * > output

Tôi muốn tăng tốc nó lên. Là một lập trình viên trong Java, tôi biết đa luồng có thể được sử dụng để tăng tốc quá trình. Tôi bị mắc kẹt về cách bắt đầu greptrong "chế độ đa luồng" và ghi đầu ra vào một outputtệp.




1
Chắc chắn tìm kiếm một bộ sưu tập lớn các tập tin là ví dụ kinh điển về một vấn đề bị ràng buộc IO. Do đó sử dụng nhiều chủ đề sẽ không giúp đỡ.
Jonathan Hartley

Câu trả lời:


31

Có hai giải pháp dễ dàng cho việc này. Về cơ bản, sử dụng xargshoặc parallel.

Cách tiếp cận xargs:

Bạn có thể sử dụng xargsvới findnhư sau:

find . -type f -print0  | xargs -0 -P number_of_processes grep mypattern > output

Nơi bạn sẽ thay thế number_of_processesbằng số lượng quá trình tối đa bạn muốn được khởi chạy. Tuy nhiên, điều này không được đảm bảo để cung cấp cho bạn một hiệu suất đáng kể trong trường hợp hiệu suất của bạn bị hạn chế I / O. Trong trường hợp đó, bạn có thể cố gắng bắt đầu nhiều quy trình hơn để bù cho thời gian bị mất đang chờ I / O.

Ngoài ra, với việc bao gồm tìm kiếm, bạn có thể chỉ định các tùy chọn nâng cao hơn thay vì chỉ các mẫu tệp, như thời gian sửa đổi, v.v ...

Một vấn đề có thể xảy ra với cách tiếp cận này như được giải thích bởi các bình luận của Stéphane, nếu có ít tệp, xargscó thể không bắt đầu đủ nhiều quy trình cho chúng. Một giải pháp sẽ là sử dụng -ntùy chọn xargsđể chỉ định số lượng đối số cần lấy từ đường ống tại một thời điểm. Cài đặt -n1sẽ buộc xargsbắt đầu một quy trình mới cho mỗi tệp duy nhất. Đây có thể là một hành vi mong muốn nếu các tệp rất lớn (như trong trường hợp của câu hỏi này) và có một số lượng tệp tương đối nhỏ. Tuy nhiên, nếu bản thân các tệp nhỏ, chi phí bắt đầu một quy trình mới có thể làm giảm lợi thế của tính song song, trong trường hợp đó, -ngiá trị lớn hơn sẽ tốt hơn. Do đó, -ntùy chọn có thể được điều chỉnh tốt theo kích thước và số tập tin.

Cách tiếp cận song song:

Một cách khác để làm điều đó là sử dụng công cụ song song Ole Tange GNU parallel, (có sẵn tại đây ). Điều này cung cấp khả năng kiểm soát hạt tốt hơn đối với sự song song và thậm chí có thể được phân phối trên nhiều máy chủ (sẽ có ích nếu thư mục của bạn được chia sẻ chẳng hạn). Cú pháp đơn giản nhất sử dụng song song sẽ là:

find . -type f | parallel -j+1 grep mypattern

trong đó tùy chọn -j+1hướng dẫn song song để bắt đầu một quá trình vượt quá số lượng lõi trên máy của bạn (Điều này có thể hữu ích cho các nhiệm vụ giới hạn I / O, thậm chí bạn có thể cố gắng tăng số lượng cao hơn).

Song song cũng có lợi thế hơn xargslà thực sự giữ lại thứ tự đầu ra từ mỗi quy trình và tạo ra đầu ra liền kề. Ví dụ, với xargs, nếu quy trình 1 tạo ra một dòng nói p1L1, quy trình 2 tạo ra một dòng p2L1, quy trình 1 tạo ra một dòng khác p1L2, đầu ra sẽ là:

p1L1
p2L1
p1L2

trong khi đó với parallelđầu ra phải là:

p1L1
p1L2
p2L1

Điều này thường hữu ích hơn xargsđầu ra.


1
Bạn có thể muốn sử dụng -nkết hợp với -P. Mặt khác, xargscó thể không sinh ra một số quy trình nếu có hai vài tệp.
Stéphane Chazelas

1
Chà, -n1 sẽ bắt đầu một cái grepcho mỗi tập tin. Trừ khi các tệp rất lớn và có rất ít trong số chúng, có lẽ bạn sẽ muốn tăng thêm một chút vì bạn sẽ dành thời gian để bắt đầu và dừng các quá trình grep thay vì tìm kiếm trong các tệp.
Stéphane Chazelas

9

Có ít nhất hai cách để tăng tốc grep CPU-khôn ngoan:

  • Nếu bạn đang tìm kiếm một chuỗi cố định thay vì một biểu thức thông thường, hãy chỉ định -Fcờ;

  • Nếu mẫu của bạn chỉ có ASCII, hãy sử dụng ngôn ngữ 8 bit thay vì UTF-8, vd LC_ALL=C grep ....

Chúng sẽ không giúp ích gì nếu ổ cứng của bạn là nút cổ chai; trong trường hợp đó có lẽ song song sẽ không giúp được gì.


1
Chỉ thấy trong man grep"Gọi trực tiếp như egrep hoặc fgrep không được chấp nhận, nhưng được cung cấp để cho phép các ứng dụng lịch sử dựa vào chúng chạy không được sửa đổi." Không chắc chắn vấn đề này thực sự, nhưng cũng giống nhưgrep -F
iyrin

1
Ngoài ra khi bạn nói "chứ không phải là một mẫu", bạn có đang đề cập đến một biểu thức thông thường không?
iyrin

Tìm kiếm "chỉ ASCII" sử dụng ít CPU hơn. Nhưng bạn cần đọc những cảnh báo được đề cập trong các bình luận tại stackoverflow.com/a/11777835/198219
famzah

3

Nếu vấn đề không bị ràng buộc I / O, bạn có thể sử dụng một công cụ được tối ưu hóa để xử lý đa lõi.

Bạn có thể muốn xem qua sift ( http://sift-tool.org , từ chối trách nhiệm: Tôi là tác giả của công cụ này) hoặc người tìm kiếm bạc ( https://github.com/ggreer/the_silver_searcher ).

trình tìm kiếm bạc có giới hạn kích thước tệp là 2GB nếu bạn sử dụng mẫu biểu thức chính quy và không phải là tìm kiếm chuỗi đơn giản.


Chắc chắn tìm kiếm một loạt các tập tin là một ví dụ cổ điển về một vấn đề bị ràng buộc IO?
Jonathan Hartley
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.