Kết hợp phủ định bằng grep (các dòng khớp không chứa foo)


990

Tôi đã cố gắng tìm ra cú pháp cho lệnh này:

grep ! error_log | find /home/foo/public_html/ -mmin -60

HOẶC LÀ:

grep '[^error_log]' | find /home/baumerf/public_html/ -mmin -60

Tôi cần phải xem tất cả các tệp đã được sửa đổi ngoại trừ những tệp có tên error_log.

Tôi đã đọc về nó ở đây , nhưng chỉ tìm thấy một notmẫu -regex.


13
[^ error_log] dù sao cũng sẽ không bao giờ hoạt động, [] là các lớp char, nói chung của regrec không tốt ở các mẫu âm (trừ khi động cơ thực hiện các giao diện phủ định).
Jaap

Câu trả lời:


1757

grep -v là bạn của bạn:

grep --help | grep invert  

-v, --invert-match chọn các dòng không khớp

Ngoài ra kiểm tra liên quan -L(bổ sung của -l).

-L, --files-without-match chỉ in tên FILE không chứa kết quả khớp


125
Đáng nói là -ecó thể sử dụng tùy chọn đối sánh nhiều (phủ định) :grep -v -e 'negphrase1' -e 'negphrase2'
Babken Vardanyan

31
Tương tự như nhận xét từ @ Babken-Vardanyan Ngoài ra - có thể sử dụng các đường ống để tham gia nhiều trận đấu, ví dụ:grep -v 'negphrase1|negphrase2|negphrase3'
Nicholas Adams

13
Nhận xét cuối cùng KHÔNG giống như nó sẽ tìm kiếm những thứ không khớp với cả hai. tức là nếu nó khớp với một nhưng không phải cái kia thì nó vẫn được in. Hãy thử cả hai cách với các chuỗi không giống nhau
Evan Langlois

7
@EvanLanglois - buộc grep diễn giải mẫu như một biểu thức chính quy mở rộng bằng cách sử dụng -Ecác tác phẩm, tức là grep -vE 'negphrase1|negphrase2|negphrase3'
Zlemini

1
@ OlleHärstedt, tôi nghĩ rằng tôi đã hiểu nhầm kịch bản của bạn trong bình luận trước đây, sau đây có thể là những gì bạn đang tìm kiếm grep "" /dev/null * | grep foo | grep -v bar | cut -d: -f1 | sort -u( tại sao grep đầu tiên ? , Luôn luôn có một cách :))
Motti

139

Bạn cũng có thể sử dụng awkcho các mục đích này, vì nó cho phép bạn thực hiện các kiểm tra phức tạp hơn theo cách rõ ràng hơn:

Các dòng không chứa foo:

awk '!/foo/'

Các dòng không chứa cũng không foophải bar:

awk '!/foo/ && !/bar/'

Các dòng không chứa foocũng không barchứa foo2hoặc bar2:

awk '!/foo/ && !/bar/ && (/foo2/ || /bar2/)'

Và như thế.


2
Điều đó thực sự khá tuyệt. Bạn thậm chí không phải học ngôn ngữ awk hoàn chỉnh để nhóm regrec với các toán tử logic. Cảm ơn câu trả lời này!
Peter T.

1
Chính xác những gì tôi đang tìm kiếm, cảm ơn rất nhiều.
mmrs151

13

Trong trường hợp của bạn, có lẽ bạn không muốn sử dụng grep, nhưng thay vào đó hãy thêm một mệnh đề phủ định vào lệnh find, vd

find /home/baumerf/public_html/ -mmin -60 -not -name error_log

Nếu bạn muốn bao gồm các ký tự đại diện trong tên, bạn sẽ phải thoát chúng, ví dụ: để loại trừ các tệp có hậu tố .log:

find /home/baumerf/public_html/ -mmin -60 -not -name \*.log
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.