Làm cách nào để tôi có thể lọc theo cách đệ quy tên của các tệp tôi muốn bằng ký tự đại diện?


40

Khi tôi muốn thực hiện tìm kiếm grep đệ quy trong thư mục hiện tại, tôi thường làm:

grep -ir "string" .

Nhưng lệnh đó tìm kiếm bên trong tất cả các loại tệp, bao gồm các tệp nhị phân (hình ảnh, âm thanh, video, v.v ...) dẫn đến quá trình tìm kiếm rất chậm.

Nếu tôi làm điều này, ví dụ, nó không hoạt động:

grep -ir "string" *.php

Nó không hoạt động vì không có tệp PHP trong thư mục hiện tại, nhưng bên trong một số thư mục con trong thư mục hiện tại và tên của các thư mục con không kết thúc bằng ".php" vì vậy grep không nhìn vào bên trong chúng.

Vì vậy, làm thế nào tôi có thể thực hiện tìm kiếm đệ quy từ thư mục hiện tại mà còn chỉ định tên ký tự đại diện? (tức là: chỉ tìm kiếm trong các tệp kết thúc bằng một phần mở rộng cụ thể)

Câu trả lời:


58

Sử dụng grep's --includelựa chọn:

grep -ir "string" --include="*.php" .

1
Ok, có vẻ như phiên bản grep của tôi đã cũ, vì nó không có tùy chọn đó (không có lý do tại sao tôi không thể tìm ra cách để làm điều này!). Tôi nhận được thông báo: "grep: tùy chọn không được nhận dạng` --include = *. Php '". Nhưng tôi chỉ nâng cấp lên một cái mới hơn và bây giờ nó hoạt động. Cảm ơn bạn!
OMA

Tôi đã phải thay thế khoảng thời gian cuối và sử dụng:grep -ir "string" --include="*.php" *
Stuart

Tôi nghĩ khoảng thời gian chỉ là kết thúc của dòng! Tôi đã không sử dụng hoặc cần.
boardtc

14

Nếu bạn có một phiên bản grepthiếu --includetùy chọn đó, bạn có thể sử dụng cách sau. Cả hai đều được thử nghiệm trên một cấu trúc thư mục như thế này:

$ tree
.
├── a
├── b
   └── foo2.php
├── c
   └── d
       └── e
           └── f
               └── g
                   └── h
                       └── foo.php
├── foo1.php
└── foo.php

Trong đó tất cả các .phptệp chứa chuỗi string.

  1. Sử dụng find

    $ find . -name '*php' -exec grep -H string {} +
    ./b/foo2.php:string
    ./foo1.php:string
    ./c/d/e/f/g/h/foo.php:string

    Giải trình

    Điều này sẽ tìm thấy tất cả .phpcác tập tin và sau đó chạy grep -H stringtrên mỗi trong số họ. Với find's -exectùy chọn, {}được thay thế bởi mỗi người trong số các tập tin được tìm thấy. Các -Hyêu cầu grepđể in tên tập tin cũng như dòng phù hợp.

  2. Giả sử bạn có phiên bản đủ mới bash, hãy sử dụng globstar:

    $ shopt -s globstar
    $ grep -H string  **/*php
    b/foo2.php:string
    c/d/e/f/g/h/foo.php:string
    foo1.php:string

    Giải trình

    Như đã giải thích trong hướng dẫn sử dụng bash :

    sao

    Nếu được đặt, mẫu '**' được sử dụng trong ngữ cảnh mở rộng tên tệp sẽ khớp với tất cả các tệp và không hoặc nhiều thư mục và thư mục con. Nếu mẫu được theo sau bởi '/', chỉ các thư mục và thư mục con phù hợp.

    Vì vậy, bằng cách chạy, shopt -s globstarbạn đang kích hoạt tính năng và globstartùy chọn của Bash , giúp **/*phpmở rộng ra tất cả .phpcác tệp trong thư mục hiện tại ( **khớp với 0 hoặc nhiều thư mục, do đó cũng **/*phpkhớp ./foo.php) string.


-2

Sử dụng */*.php

Điều này làm cho grep tìm kiếm một cấp thư mục con


Một cái gì đó đã đi sai khi dấu hoa thị và dấu chấm biến mất.
Dennis Nolan

Bạn có thể sử dụng backticks để định dạng mã và tránh sự mơ hồ về việc sử dụng dấu hoa thị để nhấn mạnh trong định dạng đánh dấu. PS lưu ý câu hỏi hỏi về "tìm kiếm đệ quy" trong đoạn cuối cùng (không phải là downvote của tôi).
RedGrittyBrick

Không phải là một câu trả lời đúng, vì nó chỉ tốt cho các cấu trúc thư mục sâu một cấp, như bạn đã đề cập, nhưng dù sao vẫn tốt để biết;). Upvote của tôi cho điều đó.
OMA
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.