Làm thế nào để tìm kiếm văn bản trong toàn bộ hệ thống tập tin?


53

Giả sử rằng công cụ grep nên được sử dụng, tôi muốn tìm kiếm chuỗi văn bản "800x600" trong toàn bộ hệ thống tệp.

Tôi đã thử:

grep -r 800x600 /

nhưng nó không hoạt động.

Điều tôi tin rằng lệnh của tôi nên làm là grep đệ quy thông qua tất cả các tệp / thư mục dưới gốc cho văn bản "800x600" và liệt kê kết quả tìm kiếm.

Tôi đang làm gì sai?


2
Và bởi "nó không hoạt động" bạn có nghĩa là chính xác những gì? Nó không in bất kỳ đầu ra, treo hoặc in nhiều Permission deniedlỗi? Bạn đã chạy nó như root hoặc người dùng bình thường?
alex

Tôi đang nhận được một số lực kéo, trước hết tôi đã ở trong thư mục nhà người dùng của mình để cố gắng chạy lệnh. Vì vậy, bây giờ tôi đã cd / out để root. Tiếp theo, tôi đã thử lệnh tương tự như trên và tôi nhận được rất nhiều lỗi bị từ chối. Ok, vì vậy bây giờ tôi thử sudo grep -r 800x600 / và sau đó tôi nhận được một / Proc / sysrq-trigger: Lỗi đầu vào / đầu ra
Level1Coder

Hmm, không biết tại sao nó sẽ không hoạt động. Bạn có thể bỏ qua lỗi truy cập bằng cách làm grep -r 800x600 / 2>/dev/null. Bạn cũng có thể thử chạy nó với quyền root.
Totor

Câu trả lời:


64

Tôi thường sử dụng kiểu lệnh này để chạy greptrên một số tệp:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

Điều này thực sự làm là tạo một danh sách của mỗi tệp trên hệ thống, và sau đó cho mỗi tệp, thực hiện grepvới các đối số đã cho và tên của mỗi tệp.

Đối -xdevsố cho biết rằng nó phải bỏ qua các hệ thống tệp khác - điều này tốt cho việc tránh các hệ thống tệp đặc biệt như /proc. Tuy nhiên, nó cũng sẽ bỏ qua các hệ thống tập tin bình thường - vì vậy, ví dụ, nếu thư mục / home của bạn nằm trên một phân vùng khác, nó sẽ không được tìm kiếm - bạn sẽ cần phải nói find / /home -xdev ....

-type fcó nghĩa là chỉ tìm kiếm các tệp, vì vậy các thư mục, thiết bị và các tệp đặc biệt khác bị bỏ qua (nó vẫn sẽ truy xuất vào các thư mục và thực thi greptrên các tệp trong đó - dù sao nó sẽ không thực thi greptrên thư mục, dù sao nó cũng không hoạt động). Và -Htùy chọn để grepbảo nó luôn in tên tệp trong đầu ra của nó.

findchấp nhận tất cả các loại tùy chọn để lọc danh sách các tập tin. Ví dụ: -name '*.txt'chỉ xử lý các tệp kết thúc bằng .txt. -size -2Mcó nghĩa là các tệp nhỏ hơn 2 megabyte. -mtime -5có nghĩa là các tập tin được sửa đổi trong năm ngày qua. Tham gia cùng với -a cho -o cho hoặc , và sử dụng '('dấu ngoặc đơn ')'để biểu thức nhóm (trong dấu ngoặc kép để ngăn vỏ giải thích chúng). Ví dụ:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

Hãy xem man findđể xem danh sách đầy đủ các bộ lọc có thể.


2
Lưu ý rằng -xdevsẽ loại trừ tất cả các hệ thống tập tin khác, không chỉ những hệ thống đặc biệt. (ví dụ: nếu bạn đã /homegắn kết như một phân vùng riêng biệt, nó sẽ không được tìm kiếm.)
cjm

Tôi đã thử chạy từng cái nhưng cả hai đều trả về lỗi -find: paths must precede expression: /
Level1Coder

1
Lưu ý: Khi các biểu thức thông thường không yêu cầu 'fgrep' nhanh hơn đáng kể so với 'grep', điều này sẽ tạo ra sự khác biệt lớn nếu bạn đang tìm kiếm một cây lớn.
Nathan Kidd

1
Bạn có thể tránh đi qua xargsvới hiệu quả có thể tốt hơn bằng cách làm find / -xdev -type f -exec grep -H '800x600' +.
Toto

3
Không, +dấu hiệu ở cuối findlệnh thực sự làm điều tương tự như xargs: nó sinh ra một grepquá trình với một vài đối số.
Toto

14

Thông thường bạn sẽ không thực sự muốn tìm kiếm MỌI THỨ trên hệ thống. Linux sử dụng các nút tệp cho tất cả mọi thứ, vì vậy một số "tệp" không phải là thứ bạn muốn tìm kiếm. Ví dụ như /dev/sdathiết bị khối vật lý cho ổ cứng đầu tiên của bạn. Bạn có thể muốn tìm kiếm các hệ thống tập tin gắn kết chứ không phải thiết bị đĩa thô. Ngoài ra, có /dev/randomnhững dữ liệu ngẫu nhiên mỗi khi bạn đọc nó. Tìm kiếm mà không có nhiều ý nghĩa. Các /prochệ thống tập tin cũng là vấn đề trong trường hợp của bạn.

Tôi sẽ giới thiệu một trong hai điều.

  1. Đừng tìm kiếm ở root, chỉ tìm kiếm những nơi có thể hữu ích. Tìm kiếm /homehoặc /usrhoặc riêng biệt /etc. Thông tin bạn đang tìm kiếm có khả năng thuộc một loại cụ thể, vì vậy dù sao nó cũng có thể nằm trong một thư mục cụ thể. Cài đặt cấu hình nên được trong /etc. Tập tin dữ liệu cá nhân của bạn nên được trong /home. Giới hạn tìm kiếm trong một lĩnh vực chính như thế này sẽ giúp giảm đáng kể các vấn đề của bạn với các greps đệ quy.

  2. Loại trừ các khu vực có vấn đề bằng cách sử dụng --exclude-dirvà một tập hợp những điều bạn biết bạn không cần như thế này:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Cuối cùng, không có gì lạ khi gặp phải một vài lỗi 'bị từ chối cấp phép' khi thực hiện một grep đệ quy lớn. Trong quá trình sử dụng thông thường, có những tập tin mà người dùng của bạn không thể đọc được. Miễn là đây chỉ là một vài tệp lẻ và không phải là những thứ như thiết bị thô cho ổ cứng của bạn hoặc toàn bộ hệ thống tệp Proc, bạn chỉ cần bỏ qua các lỗi. Trong thực tế, bạn có thể làm điều này trên dòng lệnh bằng cách gửi tất cả các lỗi vào không bao giờ không bao giờ hạ cánh:

grep -r search_string /path 2> /dev/null

3
-Iđể loại trừ nhị phân
Rahul Patil

2

Để đơn giản, tôi sẽ đề nghị ack-grep . Liên kết cho thấy nhiều trường hợp khi ack-greplà một lựa chọn tốt hơn.

Để sử dụng là, sau khi cài đặt:

ack-grep pattern /

Cảm ơn đã giới thiệu, nhưng tôi đã chạy nó và nó không thực sự mang lại cho tôi kết quả tìm kiếm mà tôi dự đoán. Có vẻ như tôi sẽ cần phải điều chỉnh nhiều cài đặt để có được những gì tôi muốn. Cho đến bây giờ câu trả lời của Richard hoạt động ngay lập tức. Sẽ xem xét điều này trong tương lai vì nó có vẻ hữu ích là tốt.
Level1Coder

1

Một cách khác để xem xét nó là cách này:

grep -r /* | grep "800x600"

0

* sau đó tôi nhận được a / Proc / sysrq-trigger: Lỗi đầu vào / đầu ra

Lệnh của bạn đang hoạt động, bạn đang gặp lỗi này vì bạn đang cố quét các tiến trình đang chạy cho một chuỗi.

Tôi khuyên bạn nên loại trừ các thư mục hệ thống với

grep -exclude-dir = {Proc, sys} "800x600" /


-3

chỉ đơn giản là đúng-

grep -r "800x600" /

-Những gì sai trong lệnh hiện tại của bạn là dấu ngoặc kép, "". Luôn đặt đối số chuỗi grepvào dấu ngoặc kép.


3
Đây không phải là vấn đề ở đây. Bạn không cần trích dẫn khi đưa ra loại đối số cụ thể này grep. Hãy thử nó và bạn sẽ thấy. Đặt chuỗi "800x600" vào một tệp và sau đó grep 800x600 filebạn sẽ thấy nó hoạt động tốt. OP rõ ràng là có một số vấn đề khác.
slm
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.