Sự khác biệt giữa các dòng * .pl và * .pl trong grep là gì? Tại sao trích dẫn thay đổi kết quả?


10

Sự khác biệt giữa:
grep "string" . -r --include *.pl

grep "string" . -r --include "*.pl"

Cái sau bao gồm các tập tin trong thư mục con trong khi cái trước thì không. Tại sao?


Sự khác biệt không nằm ở grep; nó ở trong vỏ. grepkhông bao giờ nhìn thấy các trích dẫn.
tự đại diện

Câu trả lời:


17

Các *(sao, hoặc dấu hoa thị) là một nhân vật đặc biệt được (thường) giải thích bằng vỏ trước khi nó được đưa ra lệnh. Nó (thường) được mở rộng cho tất cả các tên tệp ngoại trừ những tên có dấu chấm hàng đầu. Xem hướng dẫn bash về khớp mẫu để biết thêm thông tin.

Nếu được đặt trong dấu ngoặc kép, ngôi sao sẽ không được giải thích bởi shell và được trao cho nguyên văn lệnh.


Ví dụ giải thích. Một trích dẫn:

grep "string" . -r --include "*.pl"

Ở đây grepsẽ nhận được tùy chọn --includevới đối số *.pl. Đó là chuỗi 4 ký tự với *ký tự là ký tự đầu tiên. Những gì greplàm với chuỗi đó là hoàn toàn lên đến grep. Trong trường hợp này --includecó nghĩa là chỉ xem xét các tệp phù hợp với mẫu *.pl.

AFAIK đằng sau hậu trường gnu grep sử dụng cùng một mô hình phù hợp với lib như gnu bash.

Không được trích dẫn một:

grep "string" . -r --include *.pl

Ở đây, vỏ đầu tiên sẽ mở rộng mô hình *.plcho tất cả các tên tệp kết thúc bằng .pl. Giả sử có các tập tin foo.pl, bar.plbaz.pl. Sau khi mở rộng dòng lệnh trông như thế này:

grep "string" . -r --include foo.pl bar.pl baz.pl

Ở đây grepsẽ nhận được tùy chọn --includevới đối số foo.pl, tiếp theo là các tùy chọn bar.plbaz.pl. --include foo.plcó nghĩa là chỉ xem xét các tập tin phù hợp với mẫu foo.pl. Vì không có ký tự đại diện trong mẫu nên tệp duy nhất khớp sẽ là tệp có tên foo.pl.

Các tùy chọn bar.plbaz.plphương tiện grep cũng sẽ tìm kiếm trong các tệp đó, nhưng vì chúng không khớp với mẫu foo.plnên chúng sẽ bị bỏ qua.


Đây là một quan sát tuyệt vời. Tôi luôn tự hỏi tại sao grep -rcó vẻ không nhất quán nhưng không bao giờ nhận thấy nó chỉ khi tôi sử dụng a *.
j883376

6

Sự khác biệt là nếu bạn không trích dẫn mẫu ( *.pl) thì nó được mở rộng bằng vỏ. Ví dụ: nếu bạn chạy greptrong thư mục chứa tệp được gọi foo.pl, vì tệp *plđược mở rộng bởi trình bao, điều grepthực sự nhìn thấy là:

grep "string" . -r --include foo.pl

Vì bạn bảo nó chỉ bao gồm foo.plnên nó sẽ chỉ tìm kiếm thông qua một tệp đó.

Nếu bạn trích dẫn mẫu của mình, trình bao sẽ không mở rộng nó và grepnhận lệnh chính xác, cụ thể là

 grep "string" . -r --include *pl

peoplsẽ không được mở rộng bởi *.pl.
unxnut

@unxnut điểm tốt, trả lời chỉnh sửa.
terdon
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.