2012-05-16 27 views
62

Khi tôi muốn grep tất cả các file html trong một số thư mục, tôi làm như sauTôi làm cách nào để sử dụng tùy chọn grep --include cho nhiều loại tệp?

grep --include="*.html" pattern -R /some/path

mà hoạt động tốt. Vấn đề là làm thế nào để grep tất cả các tập tin html, htm, php trong một số thư mục?

Từ Use grep --exclude/--include syntax to not grep through certain files này, có vẻ như tôi có thể làm như sau

grep --include="*.{html,php,htm}" pattern -R /some/path

Nhưng thật đáng buồn, nó sẽ không làm việc cho tôi.
FYI, phiên bản grep của tôi là 2.5.1.

Trả lời

90

Bạn có thể sử dụng nhiều cờ --include. Này làm việc cho tôi:

grep -r --include=*.html --include=*.php --include=*.htm "pattern" /some/path/

Tuy nhiên, bạn có thể làm như Deruijter gợi ý. Này làm việc cho tôi:

grep -r --include=*.{html,php,htm} "pattern" /some/path/

Đừng quên rằng bạn có thể sử dụng findxargs cho các loại điều này để:

find /some/path/ -name "*.htm*" -or -name "*.php" | xargs grep "pattern"

HTH

+1

Tôi thấy sự cố. Tôi đã sử dụng --include = "*. {Html, php}" để ngăn trình bao mở rộng '*', đồng thời ngăn chặn trình bao mở rộng {html, php}. Có vẻ như dấu bằng trong --include = * có thể ngăn chặn trình bao mở rộng '*'. – tianyapiaozi

+0

xargs không thực sự là một thay thế; rất nhiều lần khi bạn cần tính năng này, bạn đang xử lý nhiều tệp hơn xargs sẽ xử lý. –

+2

@JamesMoore: Hãy xem [GNU Parallel] (https://www.gnu.org/software/parallel/). Nó thường có thể được sử dụng để thay thế cho 'xargs'. [This] (https://www.gnu.org/software/parallel/man.html#differences_between_xargs_and_gnu_parallel) cũng đáng đọc. HTH. – Steve

4

điều này không hoạt động?

grep pattern /some/path/*.{html,php,htm} 
+0

Không thực sự. Các tệp có thể nằm trong thư mục con của thư mục con – tianyapiaozi

9

Hãy thử loại bỏ các dấu ngoặc kép

grep --include=*.{html,php,htm} pattern -R /some/path 
+0

cũng không hoạt động. – tianyapiaozi

+0

@tianyapiaozi Hãy thử 'grep --include = \ *. {Html, php, htm} mẫu -R/some/path'. Nó làm việc cho tôi. –

0

Sử dụng grep với find lệnh

find /some/path -name '*.html' -o -name '*.htm' -o -name '*.php' -type f 
-exec grep PATTERN {} \+ 

Bạn có thể sử dụng -regex-regextype lựa chọn quá.

2

Hãy thử điều này. -r sẽ thực hiện tìm kiếm đệ quy. -s sẽ chặn các lỗi không tìm thấy tệp. -n sẽ hiển thị cho bạn số dòng của tệp nơi mẫu được tìm thấy.

grep "pattern" <path> -r -s -n --include=*.{c,cpp,C,h} 
+0

Đây là câu trả lời tốt nhất cho tôi, và tôi nghĩ bạn có thể đặt -rsn thay vì -r -s -n (nhưng đó là việc đánh bạc). – slim

+0

Thông thường tôi sử dụng ** - rns **. Để rõ ràng trong ví dụ tôi đã đề cập đến ** - r -n -s ** :-) Vui mừng vì nó đã giúp. – Pradeep

8

Sử dụng {html,php,htm} chỉ có thể làm việc như một brace expansion, mà là một chuẩn (không phải POSIX-compliant) tính năng của bash, ksh, và zsh.

  • Nói cách khác: không cố gắng sử dụng nó trong một kịch bản mà mục tiêu /bin/sh - sử dụng rõ ràng nhiều --include luận trong trường hợp đó.

  • grep chính nó không hiểu {...} ký hiệu.

Đối với một mở rộng nẹp để được công nhận, nó phải là một không thể viện chứng (một phần của) token trên dòng lệnh.

Một mở rộng cú đúp mở rộng để nhiều tranh cãi, vì vậy trong trường hợp trong tầm tay grep kết thúc lên thấy nhiều--include=... tùy chọn, cũng giống như khi bạn đã vượt qua chúng riêng rẽ.

Kết quả của sự mở rộng cú đúp là chịu globbing (mở rộng tên tập tin), trong đó có cạm bẫy:

  • Mỗi đối số kết quả hơn nữa có thể được mở rộng để phù hợp với tên tập tin nếu nó xảy ra để chứa unquoted globach siêu dữ liệu như *.
    Mặc dù điều này khó xảy ra với mã thông báo như --include=*.html (ví dụ: bạn phải có tệp theo nghĩa đen có tên là giống như --include=foo.html cho thứ gì đó phù hợp).

  • Nếu tùy chọn nullglob vỏ xảy ra phải được bật (shopt -s nullglob) và globbing trận , lập luận sẽ bỏ.

Do đó, đối với một giải pháp hoàn toàn mạnh mẽ, sử dụng như sau:

grep -R '--include=*.'{html,php,htm} pattern /some/path 
  • '--include=*.' được coi là một đen, do là đơn trích dẫn; điều này ngăn cản việc giải thích vô ý của * như một nhân vật hình cầu.

  • {html,php,htm}, các - cần thiết - không thể viện chứng cú đúp mở rộng [1] , mở rộng để lập luận, trong đó, do {...}trực tiếp sau khi '...' thẻ, bao gồm rằng Token.

  • Do đó, sau khi loại bỏ quote bằng vỏ, sau đen đối số cuối cùng được truyền cho grep:

    • --include=*.html
    • --include=*.php
    • --include=*.htm

[1] Chính xác hơn, đó là chỉ cú pháp có liên quan phần của việc mở rộng cú đúp mà phải không thể viện chứng, các yếu tố danh sách vẫn có thể được trích dẫn riêng và phải nếu chúng chứa globach siêu tốc mà có thể dẫn đến globbing không mong muốn sau khi mở rộng cú đúp; trong khi không cần thiết trong trường hợp này, các nội dung trên có thể được viết là
'--include=*.'{'html','php','htm'}

+1

Cảm ơn bạn rất nhiều vì bài đăng này. Các bài đăng tuyệt vời không chỉ trả lời câu hỏi mà còn dạy bạn điều gì đó mới mẻ! Điều này đặc biệt hữu ích cho những người trong chúng ta viết về một cái gì đó cần phải được tuân thủ POSIX. Bất kỳ ai sử dụng Mac OS X đều nên nhìn vào đây! – sabalaba

+0

@sabalaba: Tôi rất vui khi biết điều đó, nhưng rõ ràng: trong khi mở rộng cú đúp không tuân thủ POSIX, nó hoạt động với 'bash' trên bất kỳ nền tảng' bash' nào chạy trên đó. – mklement0

Các vấn đề liên quan