grep, nhưng chỉ một số phần mở rộng tập tin


966

Tôi đang làm việc để viết một số tập lệnh cho grepcác thư mục nhất định, nhưng các thư mục này chứa tất cả các loại tập tin.

Tôi muốn grepchỉ .h.cppbây giờ, nhưng có thể một vài người khác trong tương lai.

Cho đến nay tôi có:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP email@domain.com

Bất cứ ai có thể chỉ cho tôi làm thế nào bây giờ tôi chỉ thêm các phần mở rộng tập tin cụ thể?


13
Đã thử grep -r -i CP_Image ~/path1/*.{h,cpp}chưa?

8
Sử dụng Trình tìm kiếm bạc : ag -i CP_Image ~/path[1-5] | mailx -s GREP email@domain.com. Công việc hoàn thành.
Johnsyweb


Sử dụng egrep (rất có thể được cài đặt sẵn trên hệ thống của bạn), và sau đó bạn có thể sử dụng regex.
Dogweather

8
Các anh chàng GNU thực sự đã rối tung lên khi họ thêm vào -rđể greptìm kiếm các tập tin vì nó phá vỡ câu thần chú UNIX về việc có các công cụ "làm một việc và làm tốt". Có một công cụ hoàn toàn tốt để tìm các tệp có tên RẤT rõ ràng.
Ed Morton

Câu trả lời:


1354

Chỉ cần sử dụng --includetham số, như thế này:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

điều đó nên làm những gì bạn muốn

Để có lời giải thích từ câu trả lời của Hold OfferHunger bên dưới:

  • grep: chỉ huy

  • -r: đệ quy

  • -i: bỏ qua trường hợp

  • --include \*.cpp: all * .cpp: Các tệp C ++ (thoát với \ chỉ trong trường hợp bạn có một thư mục có dấu hoa thị trong tên tệp)

  • ./: Bắt đầu tại thư mục hiện tại.


123
Đối với bản ghi: -r (đệ quy) -i (trường hợp bỏ qua) --include (chỉ tìm kiếm các tệp khớp với mẫu tệp)
Luis

34
Có thể được tối ưu hóa hơn nữagrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwol

1
@Hong tài liệu mà -R dành cho các liên kết tượng trưng ở đâu?
Titus

8
Ví dụ này dường như có điểm cao vì nó bao gồm nhiều loại possibilite như vậy nhưng câu trả lời được đưa ra dưới đây của grep -r --include = *. Txt 'searchterm' ./ thực sự giải thích bản chất của câu trả lời
David Casper

10
Tại sao không sử dụng dấu ngoặc kép thay vì dấu gạch chéo ngược? ví dụ:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda

283

Một số câu trả lời có vẻ quá nặng cú pháp hoặc chúng tạo ra các vấn đề trên Máy chủ Debian của tôi. Điều này làm việc hoàn hảo cho tôi:

Cuộc cách mạng PHP: Làm thế nào để Grep các tệp trong Linux, nhưng chỉ một số phần mở rộng tệp nhất định?

Cụ thể là:

grep -r --include=\*.txt 'searchterm' ./

... hoặc phiên bản không phân biệt chữ hoa chữ thường ...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep: chỉ huy

  • -r: đệ quy

  • -i: bỏ qua trường hợp

  • --include: all * .txt: tệp văn bản (thoát với \ chỉ trong trường hợp bạn có một thư mục có dấu hoa thị trong tên tệp)

  • 'searchterm': Tìm kiếm gì

  • ./: Bắt đầu tại thư mục hiện tại.


7
Bạn nên thoát khỏi việc *sử dụng \*.cpphoặc '*.cpp'. Nếu không, nó sẽ không cho kết quả như mong đợi khi thư mục làm việc chứa một số *.txttệp.
Melebius

@Melebius bạn có thể giải thích lý do tại sao nó cần thoát - nó có liên quan gì đến các tiện ích mở rộng CPP hoặc TXT mà bạn đã đề cập không? Hay bạn chỉ sử dụng chúng làm ví dụ?
Simon East

2
@SimonEast Những tiện ích mở rộng này là những tiện ích được sử dụng trong câu hỏi và câu trả lời này, không có gì đặc biệt. Nó có thể sẽ hoạt động mà không thoát khi sử dụng --include=<pattern>nhưng điều quan trọng là thoát *với --include <pattern>(một khoảng trắng thay vì =) có cảm giác rất giống nhau.
Melebius

52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./

3
grep -rn "một số điều cần grep" --include = *. {module, inc, c, h} *
ashish

3
Câu trả lời tốt đẹp. Sạch hơn so với IMO được chấp nhận nhưng bạn nên thêm tiêu chí tìm kiếm như @ashish đã lưu ý
billynoah

Tại sao là --includetùy chọn sau kim, mà không phải với các tùy chọn khác?
vladkras

@vladkras, ý bạn là kim gì? Phải --không
nhiễm trùng

50

Làm thế nào về:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print

5
Tôi muốn đề xuất nhóm các -nameđối số. điều kỳ lạ có thể xảy ra nếu bạn không find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
nullrevolution

sử dụng với "-type f" bổ sung để bỏ qua tất cả các đối tượng thư mục, chỉ quan tâm đến các tệp.
kensai

1
Tôi đã sử dụng phương pháp này trong nhiều năm và nó hoạt động nhưng nó chậm hơn rất nhiều so với grep đệ quy kể từ khi hàm exec tìm ra một quy trình grep riêng cho mỗi tệp được tìm kiếm.
đèn hiệu

Giải quyết bình luận của @ beaudet, findcó thể tùy ý bó các đối số, giảm các yêu cầu của quy trình được gọi xuống mức tối thiểu. find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + Điều này được đề xuất nhưng không được làm nổi bật trong câu trả lời của @ fedorqui's bên dưới và là một cải tiến đáng giá. Đối -Hsố cho grep ở đây rất hữu ích khi find chỉ xác định một tệp phù hợp duy nhất. Điều này có thể loại bỏ việc sử dụng -printtrong câu trả lời. Nếu tổng danh sách các tệp của bạn đủ nhỏ, sử dụng trình bao đệ quy toàn cầu (ví dụ {path1,path2}/**/*.{cpp,h}:) có thể thích hợp hơn.
Malcolm

19

Không có tùy chọn -r trên máy chủ HP và Sun, cách này hoạt động với tôi trên máy chủ HP của tôi

find . -name "*.c" | xargs grep -i "my great text"

-i dành cho trường hợp tìm kiếm không phân biệt chuỗi


1
Tôi đã đi qua một số máy chủ cho các công ty lưu trữ web không có tùy chọn --inc loại có sẵn cho fgrep và đây là dòng lệnh mà tôi sử dụng trong các trường hợp đó.
Borgboy

Tùy chọn --include cũng không khả dụng khi sử dụng Git cho Windows (MinGW / MSys).
Darren Lewis

@DarrenLewis có sẵn trong Git Bash cho Windows. Nhưng kỳ lạ thay, nó thêm các bí danh đầy màu sắc như llnhưng không thêm --color=autovào grep.
Xeverous

Đây phải là câu trả lời được chấp nhận cho tính đầy đủ, tính di động và ngắn gọn!
Cấp Foster

12

Vì đây là vấn đề tìm tập tin, hãy sử dụng find!

Sử dụng GNU find, bạn có thể sử dụng -regextùy chọn để tìm các tệp đó trong cây thư mục có phần mở rộng là .hhoặc .cpp:

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

Sau đó, nó chỉ là vấn đề thực hiện greptrên mỗi kết quả của nó:

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

Nếu bạn không có phân phối tìm kiếm này, bạn phải sử dụng một cách tiếp cận như của Amir Afghani , sử dụng -ođể nối các tùy chọn ( tên này kết thúc bằng .hhoặc với.cpp ):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Và nếu bạn thực sự muốn sử dụng grep, hãy làm theo cú pháp được chỉ định để --include:

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^


3

ag (người tìm kiếm bạc) có cú pháp khá đơn giản cho việc này

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

vì thế

ag -G *.h -G *.cpp CP_Image <path>

sử dụng ag 2.2.0, tôi cần đặt cờ của mình lần cuối:ag _string_to_find_ -G _filename_regex_
ryanrain

3

Câu trả lời dưới đây là tốt:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Nhưng có thể được cập nhật thành:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Mà có thể đơn giản hơn.


1

Nên viết "-exec grep" cho mỗi "-o -name"

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

Hoặc nhóm chúng theo ()

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

tùy chọn '-Hn' hiển thị tên và dòng tệp.


1

Tôi biết câu hỏi này có một chút ngày, nhưng tôi muốn chia sẻ phương pháp tôi thường sử dụng để tìm tệp .c.h :

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

hoặc nếu bạn cần số dòng là tốt:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
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.