*có một đặc biệt có nghĩa là cả hai như là một vỏ globbing ký tự ( "ký tự đại diện") và như là một biểu thức chính quy metacharater . Bạn phải tính đến cả hai, mặc dù nếu bạn trích dẫn biểu thức chính quy của mình thì bạn có thể ngăn vỏ đặc biệt xử lý nó và đảm bảo rằng nó chuyển nó không thay đổi grep. Mặc dù về mặt khái niệm tương tự nhau, những gì *có nghĩa là vỏ hoàn toàn khác với ý nghĩa của nó grep.
Đầu tiên , vỏ được coi *là ký tự đại diện.
Bạn đã nói:
Cho dù biểu thức được đính kèm trong dấu ngoặc kép không làm cho sự khác biệt.
Điều đó phụ thuộc vào những tập tin tồn tại trong bất kỳ thư mục nào bạn có mặt khi bạn chạy lệnh. Đối với các mẫu có chứa dấu phân cách thư mục /, nó có thể phụ thuộc vào tệp nào tồn tại trên toàn bộ hệ thống của bạn. Bạn phải luôn trích dẫn các biểu thức chính quy cho grep- và các trích dẫn đơn thường là tốt nhất-- trừ khi bạn chắc chắn rằng mình ổn với chín loại biến đổi có khả năng gây ngạc nhiên mà trình bao thực hiện trước khi thực hiện greplệnh.
Khi shell gặp một *ký tự không được trích dẫn , nó sẽ có nghĩa là "không hoặc nhiều hơn bất kỳ ký tự nào" và thay thế từ có chứa nó bằng một danh sách tên tệp khớp với mẫu. (Tên tệp bắt đầu bằng .được loại trừ - trừ khi mẫu của bạn bắt đầu bằng . hoặc bạn đã định cấu hình trình bao của mình để bao gồm chúng.) Điều này được gọi là globalbing - và cũng bởi tên mở rộng tên tệp và mở rộng tên đường dẫn .
Hiệu ứng grepthường sẽ là tên tệp phù hợp đầu tiên được lấy làm biểu thức chính quy - ngay cả khi người đọc khá rõ ràng rằng nó không có nghĩa là một biểu thức thông thường - trong khi tất cả các tên tệp khác được liệt kê tự động từ bạn global được lấy làm tập tin bên trong để tìm kiếm kết quả khớp. (Bạn không nhìn thấy danh sách - nó được chuyển qua một cách ngẫu nhiên grep.) Bạn hầu như không bao giờ muốn điều này xảy ra.
Lý do điều này đôi khi không phải là một vấn đề - và trong trường hợp cụ thể của bạn, ít nhất là cho đến nay , nó đã không - là điều đó *sẽ bị bỏ lại một mình nếu tất cả những điều sau đây là đúng :
Không có tập tin nào có tên trùng khớp. ... Hoặc bạn đã vô hiệu hóa hình cầu trong vỏ của bạn, thường là set -fhoặc tương đương set -o noglob. Nhưng điều này là không phổ biến và bạn có thể sẽ biết bạn đã làm nó.
Bạn đang sử dụng hệ vỏ có hành vi mặc định là để *yên khi không có tên tệp phù hợp. Đây là trường hợp trong Bash, mà bạn có thể đang sử dụng, nhưng không phải trong tất cả các shell kiểu Bourne. (Ví dụ, hành vi mặc định trong Zsh shell phổ biến là dành cho các khối u để (a) mở rộng hoặc (b) tạo ra lỗi.) ... Hoặc bạn đã thay đổi hành vi này của vỏ của mình - cách thực hiện khác nhau trên vỏ.
Bạn chưa khác nói với shell của bạn để cho phép những đống để được thay thế bằng gì khi không có file phù hợp, cũng không phải để thất bại với một thông báo lỗi trong tình huống này. Trong Bash, điều đó đã được thực hiện bằng cách bật tùy chọnnullglob hoặc failglob shell tương ứng.
Đôi khi bạn có thể dựa vào # 2 và # 3 nhưng hiếm khi bạn có thể dựa vào # 1. Một greplệnh có mẫu không được trích dẫn hiện hoạt động có thể ngừng hoạt động khi bạn có các tệp khác nhau hoặc khi bạn chạy nó từ một nơi khác. Trích dẫn biểu hiện thường xuyên của bạn và vấn đề biến mất.
Sau đó, các greplệnh xử lý *như một lượng hóa.
Các câu trả lời khác - chẳng hạn như câu trả lời của Sergiy Kolodyazhnyy và bởi kos - cũng giải quyết khía cạnh này của câu hỏi này, theo những cách khác nhau. Vì vậy, tôi khuyến khích những người chưa đọc chúng làm như vậy, trước hoặc sau khi đọc phần còn lại của câu trả lời này.
Giả sử điều *đó làm cho nó thành grep - mà trích dẫn phải đảm bảo - grepsau đó lấy nó để có nghĩa là mục trước nó có thể xảy ra bất kỳ số lần nào , thay vì phải xảy ra chính xác một lần . Nó vẫn có thể xảy ra một lần. Hoặc nó có thể không có mặt ở tất cả. Hoặc nó có thể được lặp đi lặp lại. Văn bản phù hợp với bất kỳ khả năng nào sẽ được khớp.
"Mục" có nghĩa là gì?
Một nhân vật duy nhất . Kể từ btrận đấu một chữ b, b*phù hợp với không hay nhiều bs, do đó ab*cphù hợp ac, abc, abbc, abbbcvv
Tương tự như vậy, kể từ khi .trận đấu bất kỳ ký tự , .*phù hợp với không hoặc nhiều ký tự 1 , do đó a.*ctrận đấu ac, akc, ahjglhdfjkdlgjdfkshlgc, thậm chí acccccchjckhccvv Hoặc
Một lớp nhân vật . Kể từ [xy]trận đấu xhay y, [xy]*trận đấu zero ký tự trở lên trong đó mỗi một là một trong hai xhoặc y, do đó p[xy]*qphù hợp pq, pxq, pyq, pxxq, pxyq, pyxq, pyyq, pxxxq, pxxyq,, vv
Điều này cũng áp dụng đối với tốc ký hình thức của các tầng lớp nhân vật như \w, \W, \s, và \S. Vì \wkhớp với bất kỳ ký tự từ nào, \w*khớp với 0 hoặc nhiều ký tự từ. Hoặc là
Một nhóm . Kể từ \(bar\)trận đấu bar, \(bar\)*trận đấu bằng không hoặc nhiều bars, do đó foo\(bar\)*bazphù hợp foobaz, foobarbaz, foobarbarbaz, foobarbarbarbazvv
Với các tùy chọn -Ehoặc -P, hãy grepcoi biểu thức thông thường của bạn là ERE hoặc PCRE tương ứng, thay vì BRE , và sau đó các nhóm được bao quanh ( )thay vì \( \), sau đó bạn sẽ sử dụng (bar)thay vì \(bar\)và foo(bar)bazthay vì foo\(bar\)baz.
man grepở phần cuối có thể giải thích hợp lý về cú pháp BRE và ERE, cũng như liệt kê tất cả các tùy chọn dòng lệnh grepchấp nhận ở đầu. Tôi khuyên bạn nên sử dụng trang thủ công đó dưới dạng tài nguyên và tài liệu GNU Grep và trang hướng dẫn / tham khảo này (mà tôi đã liên kết với một số trang trên, ở trên).
Để thử nghiệm và học tập grep, tôi khuyên bạn nên gọi nó bằng một mẫu nhưng không có tên tệp. Sau đó, nó nhận đầu vào từ thiết bị đầu cuối của bạn. Nhập dòng; các dòng được lặp lại cho bạn là những dòng chứa văn bản mẫu của bạn phù hợp. Để thoát, nhấn Ctrl+ Dở đầu một dòng, báo hiệu kết thúc đầu vào. (Hoặc bạn có thể nhấn Ctrl+ Cnhư với hầu hết các chương trình dòng lệnh.) Ví dụ:
grep 'This.*String'
Nếu bạn sử dụng --colorcờ, grepsẽ làm nổi bật các phần cụ thể của các dòng khớp với biểu thức chính quy của bạn, điều này rất hữu ích cho cả việc tìm ra biểu thức chính quy làm gì và tìm kiếm những gì bạn đang tìm kiếm khi bạn làm. Theo mặc định, người dùng Ubuntu có bí danh Bash gây ra grep --color=autođể chạy - đủ cho mục đích này - khi bạn chạy greptừ dòng lệnh, do đó bạn có thể không cần phải vượt qua --colorthủ công.
1 Do đó, .*trong một biểu thức chính quy có nghĩa là những gì *có nghĩa là trong một vỏ toàn cầu. Tuy nhiên, điểm khác biệt là greptự động in các dòng có chứa kết quả khớp của bạn ở bất kỳ đâu trong đó, do đó, thông thường không cần thiết phải có .*ở đầu hoặc cuối của biểu thức thông thường.
* != any number of unknown characters. đọc tài liệu.)