Tìm ống vào grep -v


18

Tôi đang cố gắng tìm tất cả các tệp thuộc một loại nhất định và không chứa một chuỗi nhất định. Tôi đang cố gắng đi về nó bằng cách tìm đường dẫn đến grep -v

thí dụ:

find -type f -name '*.java' | xargs grep -v "something something"

Điều này dường như không hoạt động. Nó dường như chỉ trả về tất cả các tệp mà lệnh find tìm thấy. Những gì tôi đang cố gắng làm về cơ bản là tìm tất cả các tệp .java khớp với một tên tệp nhất định (ví dụ: kết thúc bằng 'Pb' như trong SessionPb.java) và không có 'mở rộng SomethingS Something "bên trong nó.

Sự nghi ngờ của tôi là tôi đang làm sai. Vì vậy, làm thế nào các lệnh nên trông như thế nào?


bạn có thể thêm những gì khiến bạn nghĩ rằng nó không hoạt động. có lẽ biểu hiện grep của bạn là quá rõ ràng? cần một '-i' cho trường hợp không nhạy cảm? Xem câu trả lời của tôi dưới đây quá ...
lornix

Câu trả lời:


20

Không có nhu cầu ở xargsđây. Ngoài ra, bạn cần sử dụng grepvới -Ltùy chọn (tệp không khớp), vì nếu không, nó sẽ xuất nội dung tệp thay vì tên của nó, như trong ví dụ của bạn.

find . -type f -iname "*.java" -exec grep -L "something somethin" {} \+

1
-Lđã có thương lượng, bởi vì nó có nghĩa files _without_ match. Vì vậy, bạn không cần -vtùy chọn ở đây.
vội vàng

3
không có thêm + ở cuối.
lynxlynxlynx

2
@ user946850 mỗi khi tôi viết find -exec \+ai đó viết cho tôi rằng sử dụng xargs sẽ tốt hơn nhiều. Tại sao không ai nhìn người đàn ông trước khi viết bình luận? (:
vội vàng

5
@ user946850 -exec ... {} \+không tương đương với xargs. Xin vui lòng đọc tài liệu findutils! (Tôi đã làm việc khá chăm chỉ về nó!)
James Youngman

2
@ user946850 có. Một trong những khác biệt là (theo mặc định) xargsxử lý đầu vào của nó và phân tách các đối số trên khoảng trắng. Báo giá cũng đặc biệt (theo mặc định) để xargs. Cả hai điều này đều đúng -exec ... {} +. Các phiên bản cũ xargsđược sử dụng để coi dấu gạch dưới là chỉ báo EOF, nhưng đây không còn là trường hợp nữa.
James Youngman

7

Bạn gần như đã có nó thực sự ...

find . -type f -iname "*.java" -print0 | xargs -0 grep -v "something something"

Dấu chấm '.' nói để bắt đầu từ đây. (của bạn ngụ ý nó .. nhưng không bao giờ giả định).

-iname sử dụng tìm kiếm không phân biệt chữ hoa chữ thường, chỉ trong trường hợp (hoặc chỉ trong trường hợp không có trường hợp).
-print0 gửi tên tệp đến xargs với ký tự \ x00, để ngăn các vấn đề với tên tệp có khoảng trắng trong chúng.

'-0' trên xargs nói rằng hãy mong đợi tên tệp kết thúc bằng \ x00 thay vì trả về.

và lệnh grep của bạn ...

Khá nhiều có nó.


BIÊN TẬP::

Từ cập nhật của bạn:

find . -type f -iname "*pb.java" -print0 | xargs -0 grep -iL "something"

nên giúp. (Đã thêm -L từ câu trả lời của @ rush, công việc tốt)

Tôi hiểu rằng grep của bạn cần tùy chọn '-i' hoặc ít rõ ràng hơn.

Hãy thử lệnh trong các phần ... liệu tên tệp đầu ra NÀY có vẻ phù hợp không?

find . -type f -iname "*pb.java"

Nếu vậy, thì vấn đề của bạn có thể là mẫu tìm kiếm grep của bạn không khớp (lỗi chính tả? Nó xảy ra!), Hoặc không có bất kỳ kết quả khớp nào.

Trường hợp xấu nhất tuyệt đối:

grep -riL "something" *

sẽ làm rất nhiều công việc tìm kiếm mọi thứ, nhưng sẽ cung cấp cho bạn một số đầu ra.


Tôi đã thử sửa đổi của bạn và tôi vẫn không nhận được kết quả mà tôi mong đợi. Tôi sẽ thử cập nhật câu hỏi để làm cho nó rõ ràng hơn.
Hyangelo

Nếu tác giả của câu hỏi chỉ muốn tìm tên tệp, thì grep có phải là 'grep -l -v' không?
Bruce Ediger

anh ta đang tìm kiếm nội dung cụ thể trong các tệp * .java
lornix

xargs -0 grep -v "something something"nên xargs -0 grep -v "something something" /dev/nullnếu không bạn sẽ nhận được kết quả kỳ lạ khi tìm thấy sản xuất không có tập tin phù hợp.
James Youngman

{Grin} yeah, ở đâu đó trong đó logic có tất cả lông. Không có gì giống như một thử nghiệm logic sai đảo ngược nhiều lần để làm cho đầu của bạn bị tổn thương.
lornix

4

Máy tính là một máy tính: nó đang làm những gì bạn bảo nó làm thay vì những gì bạn muốn nó làm.

grep -v "something something"in tất cả các dòng không chứa something something. Ví dụ, nó in hai dòng trong số ba dòng sau:

hello world
this is something something
something else

Để in các tệp không chứa ở extends SomethingSomethingbất cứ đâu, hãy sử dụng -Ltùy chọn:

grep -L -E 'extends[[:space:]]+SomethingSomething' FILENAME…

Một số phiên bản của grep không có -Ltùy chọn (không được chỉ định bởi POSIX ). Nếu bạn không làm như vậy, hãy in nó ra và không sử dụng mã trả về để vỏ gọi thực hiện bất cứ điều gì cần làm.

grep -q -E 'extends[[:space:]]+SomethingSomething' FILENAME ||
echo "$FILENAME"

Ngoài ra, sử dụng awk.

awk '
    FNR == 1 && NR != 1 && !found { print fn }
    FNR == 1 { fn = FILENAME; found = 0; }
    /extends[[:space:]]+SomethingSomething/ { found = 1 }
    END { if (fn != "" && !found) print fn }
'

Trên Linux hoặc Cygwin (hoặc hệ thống khác có GNU grep), bạn không cần sử dụng find, vì grepnó có khả năng đệ quy.

grep -R --include='*.java' -L -E 'extends[[:space:]]+SomethingSomething'

Nếu shell của bạn là ksh hoặc bash hoặc zsh, bạn có thể làm cho shell thực hiện khớp tên tệp. Trên bash, hãy chạy set -o globstartrước (bạn có thể đặt cái này vào trong ~/.bashrc).

grep -L -E 'extends[[:space:]]+SomethingSomething' **/*.java

Wow điều này thậm chí còn tốt hơn. Tôi đã sử dụng 'extends (/ s) + SomethingS Something' dường như hoạt động xa như tôi có thể nói. Có sự khác biệt nào với cú pháp này với cú pháp được chỉ định trong phiên bản Extended RegEx không?
Hyangelo

@Hyangelo \slà một phần mở rộng GNU grep, mà tôi nghĩ là đồng nghĩa với [[:space:]].
Gilles 'SO- đừng trở nên xấu xa'
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.