it-swarm-vi.tech

Sử dụng cú pháp grep --exclude/- bao gồm để không grep qua các tệp nhất định

Tôi đang tìm chuỗi foo= trong tệp văn bản trong cây thư mục. Đó là trên một máy Linux thông thường, tôi có bash Shell:

grep -ircl "foo=" *

Trong các thư mục cũng có nhiều tệp nhị phân khớp với "foo =". Vì các kết quả này không liên quan và làm chậm quá trình tìm kiếm, tôi muốn grep bỏ qua việc tìm kiếm các tệp này (chủ yếu là hình ảnh JPEG và PNG). Làm thế nào tôi có thể làm điều đó?

Tôi biết có các tùy chọn --exclude=PATTERN--include=PATTERN, nhưng định dạng mẫu là gì? Trang người đàn ông của grep nói:

--include=PATTERN     Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN     Recurse in directories skip file matching PATTERN.

Tìm kiếm trên grep bao gồm , grep bao gồm loại trừ , grep loại trừ và các biến thể không tìm thấy gì liên quan

Nếu có một cách tốt hơn để chỉ grepping trong một số tệp nhất định, tôi sẽ làm tất cả cho nó; di chuyển các tập tin vi phạm không phải là một lựa chọn. Tôi không thể chỉ tìm kiếm một số thư mục nhất định (cấu trúc thư mục là một mớ hỗn độn lớn, với mọi thứ ở mọi nơi). Ngoài ra, tôi không thể cài đặt bất cứ thứ gì, vì vậy tôi phải làm với các công cụ phổ biến (như grep hoặc gợi ý find ).

719
Piskvor

Sử dụng cú pháp toàn cầu Shell:

grep pattern -r --include=\*.{cpp,h} rootdir

Cú pháp cho --exclude là giống hệt nhau.

Lưu ý rằng ngôi sao được thoát bằng dấu gạch chéo ngược để ngăn nó được mở rộng bởi Shell (trích dẫn nó, chẳng hạn như --include="*.{cpp,h}", cũng sẽ hoạt động tốt). Mặt khác, nếu bạn có bất kỳ tệp nào trong thư mục làm việc hiện tại khớp với mẫu, dòng lệnh sẽ mở rộng thành một cái gì đó như grep pattern -r --include=foo.cpp --include=bar.h rootdir, chỉ tìm kiếm các tệp có tên foo.cppbar.h, rất có thể không phải là thứ bạn muốn.

689
Adam Rosenfield

Nếu bạn chỉ muốn bỏ qua các tệp nhị phân, tôi khuyên bạn nên xem tùy chọn -I (chữ hoa i). Nó bỏ qua các tập tin nhị phân. Tôi thường xuyên sử dụng lệnh sau:

grep -rI --exclude-dir="\.svn" "pattern" *

Nó tìm kiếm đệ quy, bỏ qua các tệp nhị phân và không tìm trong các thư mục ẩn Subversion, cho bất kỳ mẫu nào tôi muốn. Tôi có bí danh là "grepsvn" trên hộp của tôi tại nơi làm việc.

211
rmeador

Xin hãy xem ack , được thiết kế cho chính xác những tình huống này. Ví dụ của bạn về

grep -ircl --exclude=*.{png,jpg} "foo=" *

được thực hiện với ack như

ack -icl "foo="

bởi vì ack không bao giờ tìm trong các tệp nhị phân theo mặc định và -r được bật theo mặc định. Và nếu bạn chỉ muốn tập tin CPP và H, thì hãy làm

ack -icl --cpp "foo="
61
Andy Lester

grep 2.5.3 đã giới thiệu tham số --exclude-dir sẽ hoạt động theo cách bạn muốn.

grep -rI --exclude-dir=\.svn PATTERN .

Bạn cũng có thể đặt biến môi trường: GREP_OPTIONS = "- Elim-dir = .svn"

Tôi sẽ thứ hai Andy bầu chọn cho ack mặc dù, đó là thứ tốt nhất.

34
Corey

Tôi đã tìm thấy điều này sau một thời gian dài, bạn có thể thêm nhiều bao gồm và loại trừ như:

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js
24
Rushabh Mehta

Lệnh được đề xuất:

grep -Ir --exclude="*\.svn*" "pattern" *

là khái niệm sai, bởi vì --exclude hoạt động trên tên cơ sở. Nói cách khác, nó sẽ chỉ bỏ qua .svn trong thư mục hiện tại.

12
Nicola

Trong grep 2.5.1, bạn phải thêm dòng này vào hồ sơ ~/.bashrc hoặc ~/.bash

export GREP_OPTIONS="--exclude=\*.svn\*"
11
deric

Đôi khi tôi thấy đầu ra của grep rất hữu ích:

grep -rn "foo=" . | grep -v "Binary file"

Mặc dù vậy, điều đó không thực sự ngăn nó tìm kiếm các tệp nhị phân.

9
Aaron Maenpaa

Trên CentOS 6.6/Grep 2.6.3, tôi phải sử dụng nó như thế này:

grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"

Lưu ý thiếu dấu bằng "=" (nếu không --include, --exclude, include-dir--exclude-dir bị bỏ qua)

7
aesede

Nếu bạn không phản đối việc sử dụng find, tôi thích tính năng -Prune của nó:


find [directory] \
        -name "pattern_to_exclude" -Prune \
     -o -name "another_pattern_to_exclude" -Prune \
     -o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME

Trên dòng đầu tiên, bạn chỉ định thư mục bạn muốn tìm kiếm. . (thư mục hiện tại) là một đường dẫn hợp lệ, ví dụ.

Trên dòng thứ 2 và thứ 3, sử dụng "*.png", "*.gif", "*.jpg", v.v. Sử dụng nhiều cấu trúc -o -name "..." -Prune này khi bạn có các mẫu.

Trên dòng thứ 4, bạn cần một -o khác (nó chỉ định "hoặc" thành find), các mẫu bạn muốn và bạn cần một -print hoặc -print0 ở cuối của nó. Nếu bạn chỉ muốn "mọi thứ khác" còn lại sau khi cắt các hình ảnh *.gif, *.png, v.v., thì hãy sử dụng -o -print0 và bạn đã hoàn thành dòng thứ 4.

Cuối cùng, trên dòng thứ 5 là đường dẫn đến xargs, nó sẽ lấy từng tệp kết quả đó và lưu trữ chúng trong một biến FILENAME. Sau đó, nó sẽ chuyển grep các cờ -IR, "pattern" và sau đó FILENAME được mở rộng bởi xargs để trở thành danh sách tên tệp được tìm thấy bởi find.

Đối với câu hỏi cụ thể của bạn, tuyên bố có thể trông giống như:


find . \
     -name "*.png" -Prune \
     -o -name "*.gif" -Prune \
     -o -name "*.svn" -Prune \
     -o -print0 | xargs -0 -I FILES grep -IR "foo=" FILES
6
OnlineCop

Tôi là một phạm nhân, được cấp, nhưng đây là cách tôi ~/.bash_profile:

[.___.]

Lưu ý rằng để loại trừ hai thư mục, tôi phải sử dụng --exclude-dir hai lần.

5
4D4M

git grep

Sử dụng git grep được tối ưu hóa cho hiệu suất và nhằm mục đích tìm kiếm thông qua các tệp nhất định.

Theo mặc định, nó bỏ qua các tệp nhị phân và nó đang tôn vinh .gitignore của bạn. Nếu bạn không làm việc với cấu trúc Git, bạn vẫn có thể sử dụng nó bằng cách chuyển --no-index.

Cú pháp ví dụ:

git grep --no-index "some_pattern"

Để biết thêm ví dụ, xem:

4
kenorb

Hãy thử cái này:

[.__.] $ tìm. -name "* .txt" -type f -print | tập tin xargs | grep "foo =" | cắt -d: -f1 [.__.]

Thành lập tại đây: http://www.unix.com/Shell-programming-scripting/42573-search-files-excluding-binary-files.html

3
Gravstar

Nếu bạn tìm kiếm không đệ quy, bạn có thể sử dụng mẫu glop để khớp với tên tệp.

grep "foo" *.{html,txt}

bao gồm html và txt. Nó chỉ tìm kiếm trong thư mục hiện tại.

Để tìm kiếm trong thư mục con:

   grep "foo" */*.{html,txt}

Trong các tiểu ngành:

   grep "foo" */*/*.{html,txt}
3
Stéphane Laurent

Nhìn @ cái này.

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags
2
suhas tawade

những kịch bản đó không hoàn thành tất cả vấn đề ... Hãy thử điều này tốt hơn:

du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"

kịch bản này tốt hơn, bởi vì nó sử dụng các biểu thức chính quy "thực" để tránh các thư mục tìm kiếm. chỉ tách riêng tên thư mục hoặc tệp với "\ |" trên grep -v

thưởng thức nó tìm thấy trên Shell linux của tôi! XD

2
villalvilla

Trong các thư mục cũng có nhiều tệp nhị phân. Tôi không thể chỉ tìm kiếm một số thư mục nhất định (cấu trúc thư mục là một mớ hỗn độn lớn). Có cách nào tốt hơn để chỉ grepping trong một số tập tin nhất định?

ripgrep

Đây là một trong những công cụ nhanh nhất được thiết kế để tìm kiếm đệ quy thư mục hiện tại của bạn. Nó được viết bằng Rust , được xây dựng trên Công cụ regex của Rust để đạt hiệu quả tối đa. Kiểm tra phân tích chi tiết tại đây .

Vì vậy, bạn chỉ có thể chạy:

rg "some_pattern"

Nó tôn trọng .gitignore của bạn và tự động bỏ qua các tệp/thư mục ẩn và tệp nhị phân.

Bạn vẫn có thể tùy chỉnh bao gồm hoặc loại trừ các tệp và thư mục bằng cách sử dụng -g/--glob. Quy tắc toàn cầu khớp với .gitignore quả cầu. Kiểm tra man rg để được giúp đỡ.

Để biết thêm ví dụ, hãy xem: Làm cách nào để loại trừ một số tệp không khớp với các tiện ích mở rộng nhất định với grep?

Trên macOS, bạn có thể cài đặt qua brew install ripgrep.

2
kenorb

tìm và xargs là bạn bè của bạn. Sử dụng chúng để lọc danh sách tệp thay vì grep's --exclude

Hãy thử một cái gì đó như

find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="
2
Andrew Stein

thích hợp cho tập tin tcsh .alias:

alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'

Mất một lúc tôi mới nhận ra rằng phần {mm, m, h, cc, c} KHÔNG nên nằm trong dấu ngoặc kép. ~ Keith

1
Keith Knauber

Tùy chọn --binary-files=without-match để GNU grep làm cho nó bỏ qua các tệp nhị phân. (Tương đương với công tắc -I được đề cập ở nơi khác.)

(Điều này có thể yêu cầu một phiên bản gần đây của grep; ít nhất là 2.5.3.)

1
mjs

Để bỏ qua tất cả các kết quả nhị phân từ grep

grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'

Phần awk sẽ lọc tất cả các tệp nhị phân foo khớp với các dòng

0
lathomas64