Làm thế nào để kết hợp tìm và grep cho một tìm kiếm phức tạp? (GNU / linux, tìm, grep)


17

Tôi đang cố thực hiện tìm kiếm văn bản trong một số tệp có chung cấu trúc thư mục, nhưng không nằm trong cùng một cây thư mục, trong GNU / Linux.

Tôi có một máy chủ web có nhiều trang web có chung cấu trúc cây (khung công tác Code Igniter MVC PHP), vì vậy tôi muốn tìm kiếm trong một thư mục cụ thể xuống cây cho mỗi trang, ví dụ:

/srv/www/*/htdocs/system/application/

Trong đó * là tên trang web. Và từ các thư mục ứng dụng đó , tôi muốn tìm kiếm tất cả các cây trên lá của nó, cho một tệp * .php có một số mẫu văn bản bên trong, hãy nói "gỡ lỗi (", không cần biểu thức chính quy.

Tôi biết cách sử dụng findgrep nhưng tôi không giỏi kết hợp chúng.

Làm thế nào tôi sẽ làm điều này?
Cảm ơn trước!

Câu trả lời:


21

Thử

find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep "debug (" {} \; -print

Điều này sẽ đệ quy tìm kiếm các thư mục bên dưới applicationcho các tệp có .phpphần mở rộng và chuyển chúng đến grep.

Một tối ưu hóa về điều này sẽ được thực hiện:

find /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep -H "debug ("

Điều này sử dụng xargsđể chuyển tất cả các .phptập tin đầu ra bằng cách findlàm đối số cho một greplệnh duy nhất ; ví dụ . Các tùy chọn và tùy chọn đảm bảo khoảng trống trong tập tin và thư mục tên được xử lý một cách chính xác. Cácgrep "debug (" file1 file2 file3-print0find-0xargs-H tùy chọn thông qua để grepđảm bảo rằng các tên tập tin được in trong mọi tình huống. (Theo mặc định, chỉ grepin tên tệp khi nhiều đối số được truyền vào.)

Từ người đàn ông xargs:

-0

      Các mục đầu vào được kết thúc bằng ký tự null thay vì khoảng trắng và dấu ngoặc kép và dấu gạch chéo ngược không đặc biệt (mọi ký tự được lấy theo nghĩa đen). Vô hiệu hóa kết thúc chuỗi tệp, được xử lý như bất kỳ đối số khác. Hữu ích khi các mục đầu vào có thể chứa khoảng trắng, dấu ngoặc kép hoặc dấu gạch chéo ngược. -print0Tùy chọn tìm GNU tạo ra đầu vào phù hợp cho chế độ này.


1
+1. Điều đó sẽ thực thi grep cho mỗi tệp php, mặc dù. Nếu có nhiều tệp, bạn có thể tối ưu hóa thêm bằng cáchfind /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Jukka Matilainen

@jackem Đồng ý. Tôi sẽ cập nhật câu trả lời của tôi cho phù hợp.
nagul

2
Một cải tiến nhỏ khác: xargs có thể chuyển một tên tệp cho grep, trong trường hợp đó grep sẽ không hiển thị tên tệp nếu có kết quả khớp. Bạn có thể muốn thêm -H vào lệnh grep để buộc nó hiển thị tên tệp.
Randy Orrison

@Randy Đó là một điểm rất hợp lệ.
nagul

3
Đây là sự cần thiết thực sự, nhưng GNU findcó thể đưa +toán tử thay vì \;thực hiện cùng một kiểu thực thi quy trình đơn lẻ xargs. Do đó, find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +thực hiện tương tự như xargsví dụ trong câu trả lời này, nhưng với một quá trình xử lý ít hơn (và vẫn có 0 rủi ro cho các rắc rối tên tệp).
Daniel Andersson

10

findthậm chí không cần thiết cho ví dụ này, người ta có thể sử dụng greptrực tiếp (ít nhất GNU grep):

grep -RH --include='*.php' "debug (" /srv/www/*/htdocs/system/application/

và chúng tôi đang xuống một ngã ba quá trình duy nhất.

Tùy chọn:

  • -R, --dereference-recursive Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
  • -H, --with-filename Print the file name for each match. This is the default when there is more than one file to search.
  • --include=GLOB Search only files whose base name matches GLOB (using wildcard matching as described under --exclude).
  • --exclude=GLOB Skip any command-line file with a name suffix that matches the pattern GLOB, using wildcard matching; a name suffix is either the whole name, or any suffix starting after a / and before a +non-/. When searching recursively, skip any subfile whose base name matches GLOB; the base name is the part after the last /. A pattern can use *, ?, and [...] as wildcards, and \ to quote a wildcard or backslash character literally.

Chỉ vì tò mò, các -RHtùy chọn có ý nghĩa gì?
Gus

@Gus: Đã thêm man grepđoạn trích mô tả tùy chọn vào bài viết.
Daniel Andersson

0

Shell của bạn có thể tìm thấy các tập tin php và đưa chúng cho grep. Trong bash:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
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.