toán tử grep uy + + không hoạt động


31

Điều này

ls -l /var/log | awk '{print $9}' | grep "^[a-z]*\.log."

đầu ra này:

alternatives.log.1
alternatives.log.10.gz
alternatives.log.2.gz
alternatives.log.3.gz
alternatives.log.4.gz
alternatives.log.5.gz
alternatives.log.6.gz
alternatives.log.7.gz
alternatives.log.8.gz
alternatives.log.9.gz
apport.log.1
apport.log.2.gz
apport.log.3.gz

nhưng điều này:

ls -l /var/log | awk '{print $9}' | grep "^[a-z]+\.log."

đầu ra không có gì.

Tại sao? Tôi chỉ đổi *thành +. Nó không giống nhau à? Toán tử +chỉ cần ít nhất một trận đấu, và *không hoặc nhiều hơn.

Câu trả lời:


36

Điều này là do grep(không có bất kỳ đối số nào) chỉ hoạt động với các biểu thức chính quy chuẩn. +là một phần của các biểu thức chính quy mở rộng, vì vậy để sử dụng nó, bạn cần sử dụng grep -Ehoặc egrep:

ls -l /var/log | awk '{print $9}' | grep -E "^[a-z]+\.log."

Ngoài ra, bạn chỉ có thể làm điều này nếu bạn không muốn sử dụng các biểu thức chính quy mở rộng:

ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."

Cảm ơn. Bây giờ tôi về cách giải quyết đó, nhưng tôi đã tự hỏi tại sao "+" không hoạt động. Bây giờ tôi biết. Cảm ơn một lần nữa.
Marko

11

Để giải thích về câu trả lời của MiJyn, "các ký tự đặc biệt" như + cũng hoạt động trong regex tiêu chuẩn, nhưng bạn cần phải thoát chúng bằng dấu gạch chéo ngược. Bạn có thể nói, các kỳ vọng mặc định được đảo ngược giữa regex tiêu chuẩn và mở rộng:

Trong regex tiêu chuẩn, các ký tự khớp theo nghĩa đen theo mặc định. Ví dụ: trong grep "ab+"+ là một chữ +. Ví dụ, regex sẽ tìm "ab + ab", nhưng không phải "abbbb". Để sử dụng "ý nghĩa đặc biệt" của +, bạn cần thoát khỏi nó. Vì vậy, grep "ab\+"sẽ tìm thấy "abbb", nhưng không còn "ab + ab" nữa. Bởi vì trong ví dụ cuối, dấu + được hiểu là bộ định lượng "một hoặc nhiều trong số đó", trong trường hợp đó là "một hoặc nhiều b".

Trong regex mở rộng, nó chính xác theo cách khác. Tại đây, bạn cần thoát khỏi "các ký tự đặc biệt" để được đối xử theo đúng nghĩa đen. Vì vậy, grep -E "ab+"tìm thấy "abbb", nhưng không phải "ab + ab". Nếu bạn thoát khỏi dấu +, nó sẽ được khớp theo nghĩa đen. Vì vậy, grep -E "ab\+"tìm thấy "ab + ab", nhưng không phải "abbb".


1
Thật là một mớ hỗn độn di sản ... ;-) như phép thuật và siêu nhân lại trong vim. Urgh. Cái giá phải trả cho khả năng tương thích ngược ...
Rmano
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.