Làm thế nào để grep, loại trừ một số mẫu?


84

Tôi muốn tìm các dòng trong tệp có sự xuất hiện của một số mẫu và không có một số mẫu khác. Ví dụ: tôi cần tìm tất cả các tệp / dòng bao gồm loomngoại trừ những tệp có gloom. Vì vậy, tôi có thể tìm thấy loombằng lệnh:

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

Bây giờ, tôi muốn tìm kiếm loomloại trừ gloom. Tuy nhiên, cả hai lệnh sau đều không thành công:

grep -v 'gloom' -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)
grep -n 'loom' -v 'gloom' ~/projects/**/trunk/src/**/*.@(h|cpp)

Tôi phải làm gì để đạt được mục tiêu của mình?

CHỈNH SỬA 1: Ý tôi làloomgloomlà các chuỗi ký tự (không nhất thiết là các từ). Vì vậy, tôi cần, ví dụ,bloombergtrong đầu ra lệnh và không cầnungloomy.

CHỈNH SỬA 2: Có mẫu kỳ vọng của tôi. Cả hai dòng sau đều nằm trong đầu ra lệnh:

Tôi đối mặt với những biểu tượng lấp ló qua tấm màn trầm hương.

Arty đang chìm trong một ngày ảm đạm .

Cả hai dòng sau không có trong đầu ra lệnh:

Thật là u ám khủng khiếp - những người vẽ ngu ngốc tuyệt vời o 'những chiếc áo khoác.

Ở vòng tây nam của đại sảnh pyntit


Bạn đang tìm kiếm các tệp phù hợp với tiêu chí của bạn về các dòng phù hợp với tiêu chí của bạn?
Juto

Tôi đang tìm các tệp có dòng phù hợp với tiêu chí của tôi. Và tôi muốn xem danh sách tất cả các bộ tên tệp + số dòng phù hợp + chính dòng phù hợp.
Loom

Nếu dòng là there is a loom in the gloom- bạn có muốn dòng đó được in không? Chỉ cố gắng hiểu xem bạn chỉ đang tìm kiếm các dòng có khung dệt xuất hiện khác với một phần của sự u ám hoặc nếu bạn thực sự muốn loại trừ các dòng có chứa sự u ám ngay cả khi khung dệt xuất hiện ở nơi khác trên đường dây. Đăng một số đầu vào mẫu và đầu ra dự kiến ​​sẽ hữu ích.
Ed Morton

Vì vậy, câu hỏi của bạn thực sự là How do I find lines containing the string "loom" where "loom" is not preceded by the letter "g"? Nếu bạn đăng một số đầu vào mẫu và đầu ra mong muốn sẽ giúp ích rất nhiều. Câu trả lời cho câu hỏi đó có trong các câu trả lời dưới đây.
Ed Morton

1
@EdMorton - Vâng, bạn nói đúng - Tôi cần tất cả các dòng, nơi xảy ra loommà không có trước g. (Tôi xin lỗi tôi bắt đầu bình luận ngày hôm qua, nhưng không bao giờ kết thúc vô tình nhận xét này được gửi đi...)
Loom

Câu trả lời:


102

Làm thế nào về việc chỉ chuỗi các quả lựu đạn?

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'

13
Vừa kịp giờ. Hoạt động hoàn hảo. -v là tùy chọn để loại trừ. Cảm ơn
Ravi Krishna P

2
Từ câu hỏi: Vì vậy, tôi cần, ví dụ, bloombergtrong đầu ra lệnh và không cần ungloomy. Nếu một dòng duy nhất chứa "… và bloomberg là không rõ ràng về triển vọng ...", bạn sẽ loại bỏ dòng đó nhưng nó được muốn (vì nếu chứa bloomberg).
Jonathan Leffler

23

Một giải pháp khác mà không cần chuỗi grep:

egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

Giữa các dấu ngoặc, bạn loại trừ ký tự gtrước bất kỳ sự xuất hiện nào của loom, trừ khi loomlà các ký tự đầu tiên của dòng.


9

Một chút cũ, nhưng ôi thôi ...

Giải pháp được bình chọn nhiều nhất từ ​​@houbysoft sẽ không hoạt động vì điều đó sẽ loại trừ bất kỳ dòng nào có "u ám" trong đó, ngay cả khi nó có "loom". Theo mong đợi của OP, chúng tôi cần đưa vào các dòng có "loom", ngay cả khi chúng cũng có "u ám" trong đó. Dòng này cần có trong đầu ra "Arty đang chìm trong một ngày u ám", nhưng dòng này sẽ bị loại trừ bởi một chuỗi liên kết như

grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'

Thay vào đó, ví dụ egrep regex của Bentoy13 hoạt động tốt hơn

egrep '(^|[^g])loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

vì nó sẽ bao gồm bất kỳ dòng nào có "loom" trong đó, bất kể nó có "u ám" hay không. Mặt khác, nếu nó chỉ có sự u ám, nó sẽ không bao gồm nó, đó chính xác là hành vi OP muốn.


8

Chỉ cần sử dụng awk, nó đơn giản hơn nhiều so với grep trong việc cho phép bạn thể hiện rõ ràng các điều kiện phức hợp.

Nếu bạn muốn bỏ qua các dòng chứa cả hai loomgloom:

awk '/loom/ && !/gloom/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)

hoặc nếu bạn muốn in chúng:

awk '/(^|[^g])loom/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)

và nếu thực tế là bạn chỉ muốn các dòng loomtự nó xuất hiện như một từ:

awk '/\<loom\>/{ print FILENAME, FNR, $0 }' ~/projects/**/trunk/src/**/*.@(h|cpp)

3
Hãy suy nghĩ về cách bạn muốn viết một lệnh grep để có được dòng có chứa abcdefghitheo thứ tự nào. Bây giờ so sánh điều đó với awk '/abc/ && /def/ && /ghi/'. Bây giờ hãy nghĩ về cách tương đương với grep awk '/loom/ && !/gloom/'được viết trong các câu trả lời trên trang này.
Ed Morton

Tôi không rành về awk lắm, hình như có sách nói về lệnh này. Hiện tại tôi vẫn ổn với grep, có lẽ một ngày nào đó tôi sẽ nói điều tương tự như bạn đã làm. :)
Juto

2
awk là công cụ UNX tiêu chuẩn (tức là có sẵn trên TẤT CẢ các bản cài đặt UNIX) để xử lý các tệp văn bản. Đó là những gì nó được phát minh ra để làm và nó rất giỏi. Nếu bạn đang sử dụng UNIX và phân tích cú pháp tệp văn bản, hãy tìm hiểu awk từ cuốn sách Lập trình Awk hiệu quả, Ấn bản thứ ba của Arnold Robins. Có một sự thay đổi mô hình nhỏ để vượt qua liên quan đến condition { action }cú pháp awks nhưng sau đó thật dễ dàng đối với bất kỳ ai có kinh nghiệm ngôn ngữ C hoặc Algol-base khác.
Ed Morton

Phần thưởng: đầu ra như grep -Hn --color:awk '/loom/ && !/gloom/ { gsub(/loom/, color("1;31") "&" color(0)); print color(35) FILENAME color(36) ":" color(32) FNR color(36) ":" color(0) $0; }; function color(c) { return "\033[" c "m"; }'
rối

6

-v là cờ "kết hợp ngược", vì vậy đường ống là một cách rất tốt:

grep "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)| grep -v "gloom"


5

/ * Bạn có thể đang nhìn thứ gì đó như thế này?

grep -vn "gloom" `grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp)`

BACKQUOTES được sử dụng giống như dấu ngoặc cho các lệnh, vì vậy trong trường hợp này khi -lđược kích hoạt, mã trong BACKQUOTES sẽ trả về cho bạn tên tệp, sau đó với -vn để thực hiện những gì bạn muốn: có tên tệp, số vải và cả các dòng thực tế.

CẬP NHẬT Hoặc với xargs

grep -l "loom" ~/projects/**/trunk/src/**/*.@(h|cpp) | xargs grep -vn "gloom"

Hy vọng điều đó sẽ hữu ích. * /

Hãy bỏ qua những gì tôi đã viết ở trên, nó là rác rưởi.

grep -n "loom" `grep -l "loom" tt4.txt` | grep -v "gloom"

               #this part gets the filenames with "loom"
#this part gets the lines with "loom"
                                          #this part gets the linenumber,
                                          #filename and actual line

4

Bạn có thể sử dụng grep -P(perl regex) được hỗ trợ negative lookbehind:

grep -P '(?<!g)loom\b' ~/projects/**/trunk/src/**/*.@(h|cpp)

Tôi đã thêm \bcác ranh giới từ.


2
Bạn không cần phải trông đợi, \([^g]\|^\)hoạt động. Và điều này không loại trừ các dòng có cả hai loomgloom.
Kevin

@Kevin: OP muốn tìm dòng bằng khung dệt nhưng not gloom.
anubhava

Chính xác. Nếu một dòng có cả hai, anh ta không muốn nó nhưng điều này sẽ phù hợp với nó.
Kevin

@Kevin: Điều này KHÔNG phù hợp với u ám nhưng sẽ phù hợp với khung cửi (như OP muốn).
anubhava

Từ câu hỏi: Vì vậy, tôi cần, ví dụ, bloombergtrong đầu ra lệnh và không cần ungloomy. Như vậy, các ranh giới từ là phản tác dụng.
Jonathan Leffler

3
grep -n 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp) | grep -v 'gloom'

Từ câu hỏi: Vì vậy, tôi cần, ví dụ, bloombergtrong đầu ra lệnh và không cần ungloomy. Nếu một dòng duy nhất chứa "… và bloomberg là không rõ ràng về triển vọng ...", bạn sẽ loại bỏ dòng đó nhưng nó được muốn (vì nếu chứa bloomberg).
Jonathan Leffler

@JonathanLeffler "Tôi cần tìm tất cả các tệp / dòng bao gồm khung dệt trừ những tệp có màu u ám."
Jiminion

3

Đơn giản chỉ cần sử dụng! grep -vnhiều lần.

Nội dung của tệp

[root@server]# cat file
1
2
3
4
5

Loại trừ dòng hoặc khớp

[root@server]# cat file |grep -v 3
1
2
4
5

Loại trừ dòng hoặc so khớp nhiều

[root@server]# cat file |grep -v 3 |grep -v 5
1
2
4

0

Câu hỏi: tìm kiếm từ 'loom' trừ 'u ám'.
Câu trả lời:

grep -w 'loom' ~/projects/**/trunk/src/**/*.@(h|cpp)

1
Từ câu hỏi: Vì vậy, tôi cần, ví dụ, bloombergtrong đầu ra lệnh và không cần ungloomy. Tôi không nghĩ đó -wlà giải pháp cho câu hỏi hóc búa đó.
Jonathan Leffler
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.