Câu hỏi Cách sử dụng lệnh “grep” để tìm văn bản bao gồm các thư mục con


Tôi muốn tìm tất cả các tệp có chứa một chuỗi văn bản cụ thể. Các grep lệnh hoạt động, nhưng tôi không biết cách sử dụng nó cho mỗi thư mục (tôi chỉ có thể làm điều đó cho thư mục hiện tại của mình). Tôi đã cố gắng đọc man grep, nhưng nó không mang lại sự giúp đỡ nào.


293
2017-08-01 11:38


gốc


grep -Rin <yor pattern> * Sẽ tìm kiếm từ các thư mục hiện tại trong tất cả các tệp văn bản. Không chắc chắn cách tìm kiếm đệ quy trong các mẫu tệp như * .C chỉ với grep
Ký tự đại diện với --include="*.C" tùy chọn, @ user311346, nhờ @Lekensteyn. - Bob Stein
Sử dụng kết hợp tìm và grep để đệ quy tìm kiếm tệp cho chuỗi trong thư mục con hiện tại và tất cả thư mục con. Kiểm tra điều này wilddiary.com/find-files-containing-my-text - Drona


Các câu trả lời:


Sẽ tốt hơn nếu sử dụng

grep -rl "string" /path

Ở đâu

  • -r (hoặc là --recursive) được sử dụng để duyệt qua tất cả các thư mục con của /path, trong khi
  • -l (hoặc là --files-with-matches) tùy chọn được sử dụng để chỉ in tên tập tin của các tập tin phù hợp, và không phải là các dòng phù hợp (điều này cũng có thể cải thiện tốc độ, cho rằng grep dừng đọc một tập tin ở lần khớp đầu tiên với tùy chọn này).

376
2017-08-01 11:55



Trên thực tế, nếu "chuỗi" là mẫu văn bản cần tìm, tốt hơn nên sử dụng chức năng đó, nếu không ai đó có thể gặp sự cố khi chuỗi chứa dấu chấm hoặc ký tự đặc biệt có ý nghĩa trong cụm từ thông dụng chứ không chỉ là dấu chấm. , như là. Sau đó, tôi sẽ sử dụng -rlF công tắc, -F cho "chuỗi cố định" (và không phải regexp - ví dụ). Tất nhiên, nếu nhiệm vụ đã được sử dụng regexps, sau đó tha cho tôi. Chắc chắn, cùng một lý thuyết mà không -r, tôi thường thấy rằng mọi người giả định grep tìm kiếm "văn bản" và nó có thể gây ra vấn đề mà những người đặc biệt có nghĩa là một cái gì đó như là một regexp. - LGB
Ngoài ra còn có -i cờ bỏ qua trường hợp. - Marco Ceppi♦
Tôi sẽ chỉ hiển thị --recursive tùy chọn, có rất nhiều tùy chọn và kịch bản sử dụng mà người dùng có thể nói đến. Tôi bắt đầu từ câu trả lời được chấp nhận @dmityugov và được sửa đổi để hoạt động mà không cần find. - enzotib
@ N.N .: done :-) - enzotib
@ScottBiggs: với tùy chọn --include '*.h' - enzotib


Nếu bạn đang tìm kiếm các dòng phù hợp trong các tệp, lệnh yêu thích của tôi là:

grep -Hrn 'search term' path/to/files
  • -H làm cho tên tệp được in (ngụ ý khi nhiều tệp được tìm kiếm)
  • -r tìm kiếm đệ quy
  • -n làm cho số dòng được in

path/to/files có thể . để tìm kiếm trong thư mục hiện tại

Các tùy chọn khác mà tôi thấy rất hữu ích:

  • -I bỏ qua các tệp nhị phân (bổ sung: -a xử lý tất cả các tệp dưới dạng văn bản)
  • -F đãi search term như một nghĩa đen, không phải là một biểu thức chính quy
  • -i thực hiện tìm kiếm phân biệt chữ hoa chữ thường
  • --color=always để buộc màu sắc ngay cả khi đường ống qua less. Để làm cho less hỗ trợ màu sắc, bạn cần phải sử dụng -r Tùy chọn:

    grep -Hrn search . | less -r
    
  • --exclude-dir=dir hữu ích để loại trừ các thư mục như .svn và .git.

Example output


138
2017-08-01 12:27



-H trên một thư mục là dư thừa, nếu có nhiều hơn thì một tập tin, như là có thể xảy ra. Trong thực tế, trang người đàn ông nói -H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search. - enzotib
Tôi không biết điều đó, nó luôn hoạt động như tôi mong đợi. Đó là lệnh mặc định của tôi khi tìm kiếm tệp. - Lekensteyn
Có cách nào để chỉ xem xét các tập tin với một, nói, .a extention (và để kết hợp này với -r)? - user2413
@ user2413 Thử --include '*.*' - Lekensteyn
@enzotib Chỉ cần một FYI: Tôi không nhận được đầu ra sạch đẹp của mỗi dòng trong mỗi tập tin mà văn bản của tôi xuất hiện với -rln cũng không -rl, nhưng tôi làm với -Hrn. Dự phòng hay không, có vẻ như ảnh chụp màn hình ở trên có các tùy chọn -Hrn. Ngoài ra, nó không có vẻ như -n hoạt động mà không có -H. - SgtPooki


Tôi tin rằng bạn có thể sử dụng một cái gì đó như thế này:

find /path -type f -exec grep -l "string" {} \;

Giải thích từ nhận xét

find là một lệnh cho phép bạn tìm các tệp và các đối tượng khác như thư mục và liên kết trong các thư mục con của một đường dẫn cụ thể. Nếu bạn không chỉ định một mặt nạ mà tên tệp phải đáp ứng, nó liệt kê tất cả các đối tượng thư mục.

  • -type f chỉ định rằng nó sẽ chỉ xử lý các tệp, chứ không phải các thư mục, v.v.
  • -exec grep xác định rằng đối với mọi tệp được tìm thấy, nó sẽ chạy lệnh grep, chuyển tên tệp của nó làm đối số cho nó, bằng cách thay thế {} với tên tệp

21
2017-08-01 11:48



Chỉ dành cho những người không biết, thêm -name '*.py' hạn chế các kết quả phù hợp với các tệp kết thúc bằng '.py'. - Daniel F
Tôi thích rằng điều này bao gồm các khách hàng không có -R thực hiện trong lệnh grep của họ. - Aviose


Lệnh mặc định của tôi là

grep -Rin string *

Tôi sử dụng một thủ đô 'R' vì ls sử dụng nó cho đệ quy. Kể từ khi grep chấp nhận cả hai, không có lý do để không sử dụng nó.

EDIT: mỗi HVNSweeting, rõ ràng -R sẽ theo các liên kết tượng trưng trong đó -r sẽ không.


17
2017-08-01 14:43



Để tìm kiếm trong các tập tin ẩn quá, chạy shopt -s dotglob (nhớ lại -s là "set"). Hãy cẩn thận khi loại bỏ các tập tin sau đó. Nếu bạn đã bật dotglob, rm -r * loại bỏ mọi thứ trong thư mục hiện tại, nhưng cũng thếthư mục phía trên nó bởi vì .. kết quả phù hợp. Để tắt dotglob, hãy sử dụng shopt -u dotglob ("bỏ đặt"). Các thay đổi tạm thời, mặc dù nó chỉ áp dụng cho shell hiện tại. - Lekensteyn
Tôi quên mất điều này. Có cách nào để đặt nó cho một dòng không? cái gì đó như shopt -s dotglob & <grep cmd> & shopt -y dotglob chỉ thuận tiện hơn? Bằng cách này, chúng tôi sẽ không phải lo lắng về việc đặt lại - user606723
Ngoài ra, nó có thể dễ dàng hơn để sử dụng grep -Rin string . trong hầu hết các trường hợp này. Tôi chỉ sử dụng * bởi vì nó có vẻ tự nhiên hơn. - user606723
nếu bạn làm grep đệ quy, thì bạn chỉ có thể bắt đầu từ "." thay vì "*". không cần dotglob. - Michał Šrajer
bỏ phiếu này, một điều không đề cập đến trong manpage là R sẽ theo các liên kết tượng trưng, r không làm - HVNSweeting


Nếu bạn sẵn sàng thử một cái gì đó mới, hãy cho ack một shot. Lệnh để đệ quy tìm kiếm thư mục hiện tại cho string Là:

ack string

Cài đặt khá đơn giản:

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(Miễn là bạn đã có thư mục ~/bin và tốt nhất là trong PATH.)


11
2017-08-01 15:09



Hoặc chỉ cần apt-get cài đặt ack-grep (và thêm bí danh ack = ack-grep vào .bashrc của bạn) - markijbema
Các thông số cuối cùng cho chmod lệnh làm gì? Chúng có cụ thể cho chmod hoặc họ có liên quan đến bash ( !#:3 phần)? - Elliott Darfink
@ElliottDarfink Đó là sử dụng Bash tính năng lịch sử - - ! là một người thiết kế sự kiện. Chúng khá mạnh mẽ để tránh lặp lại. !#:3 tham chiếu đến mã thông báo thứ ba của dòng lệnh cho đến nay, tức là ~/bin/ack trong trường hợp này. - Konrad Rudolph


Lệnh rgrep được dành riêng cho nhu cầu đó

Nếu không có, bạn có thể làm như thế này

mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep

Bạn có thể trực tiếp đặt vào các tùy chọn grep mặc định của bạn như được mô tả ở trên.

Tôi sử dụng personnaly

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"

chủ đề có liên quan : làm thế nào để luôn luôn sử dụng rgrep với màu sắc


3
2018-01-02 13:58



rgrep được cung cấp bởi gói grep được cài đặt mặc định trong Ubuntu. - karel


Cập nhật 2:

Dòng lệnh này sử dụng find và grep khắc phục sự cố:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> cho đầu ra màu:

$ find path_to_search_in -type f \
            -exec grep --color=always -in searchString {} 2>/dev/null +

Thí dụ:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

Một ví dụ chạy trong ảnh chụp bên dưới: snap1


Cập nhật 1:

Bạn có thể thử mã sau; như một chức năng trong .bashrchoặc là .bash_aliases hoặc trong một tập lệnh:

wherein () 
{ 
    for i in $(find "$1" -type f 2> /dev/null);
    do
        if grep --color=auto -i "$2" "$i" 2> /dev/null; then
            echo -e "\033[0;32mFound in: $i \033[0m\n";
        fi;
    done
}

Sử dụng: wherein /path/to/search/in/ searchkeyword

thí dụ:

$ wherein ~/Documents/ "hello world"

(Lưu ý: Như được đề xuất trong các bình luận dưới đây bởi @enzotib, điều này không làm việc với các tập tin / thư mục bao gồm cả không gian trong tên của chúng.)


Bài đăng gốc

Để tìm chuỗi và xuất chỉ dòng đó bằng chuỗi tìm kiếm:

$ for i in $(find /path/of/target/directory -type f); do \
    grep -i "the string to look for" "$i"; done

ví dụ.:

$ for i in $(find /usr/share/applications -type f); \
    do grep -i "web browser" "$i"; done

Để hiển thị tên tệp chứa chuỗi tìm kiếm:

$ for i in $(find /path/of/target/directory -type f); do \
    if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

ví dụ.:

$ for i in $(find /usr/share/applications -type f); \
    do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
    fi; done;

2
2018-01-25 11:11



Không có tên tệp có chứa dấu cách. Sự thất bại được che giấu bởi thực tế là stderr không được hiển thị. - enzotib
@enzotib cảm ơn vì đã chỉ ra điều đó .. vẫn chưa được giải quyết cho hàm được chỉ định .. Tôi đã thêm một lớp lót khác mặc dù .. - precise
Bây giờ câu trả lời là tương tự như của @dmityugov. - enzotib
vâng, nhưng theo nghĩa đó, hầu hết các câu trả lời trong trang này nếu bạn kiểm tra tương tự về mặt mà họ sử dụng grep, bên cạnh đó là tập con bằng cách sử dụng find với grep... nhưng nếu bạn chấp nhận các công tắc và công tắc khác nhau như một câu trả lời khác biệt, có lẽ tôi cũng sẽ phù hợp ở đây ... hoặc bạn có khác biệt không? bản cập nhật cuối cùng thực hiện những gì tôi muốn trong tìm kiếm của mình: tên tệp có các dòng có khóa tìm kiếm và dòng không. quá :) và đầu ra màu và bộ lọc lỗi để dễ đọc hơn .. - precise


Tôi làm điều này bằng cách sử dụng xargs, một lệnh rất bị đánh giá thấp

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

find ./ cung cấp cho bạn danh sách đệ quy của tất cả các tệp trong thư mục hiện tại sau đó bạn đặt nó vào xargs thực hiện lệnh grep trên mỗi tệp


1
2017-08-01 15:30



Sử dụng xargs không có -print0 tùy chọn để find và -0 tùy chọn để xargs không được chấp nhận, nó sẽ không thành công trên tên tệp có chứa dấu cách. - enzotib
@enzotib Tôi đã chỉnh sửa câu trả lời như bạn đã đề xuất.- vui lòng xem lại và nếu cần chỉnh sửa và chỉnh sửa, tôi sẽ vui lòng chỉnh sửa lại bởi bạn. cảm ơn bạn - αғsнιη
@ KasiyA: nó là ok bây giờ, loại bỏ downvote của tôi. - enzotib