Làm cách nào để tìm văn bản trong một tệp và để nó tìm kiếm nhiều thư mục con?


7

Tôi đang tìm một tên hàm và cấu trúc thư mục sâu và có rất nhiều tệp để xem.

Thông thường tôi đi với một cái gì đó như find * | grep functionnamenhưng đó là cách tốt nhất?


Duh cái gì? findchỉ tìm thấy tên tập tin , không phải nội dung.
Hello71

Bạn đã từng nghe về xargs? Hoặc -execchính trong find?
geekizard

Này anh bạn, tôi đã nói đó là những gì tôi đã sử dụng, không phải nó hoạt động! Tại sao bạn nghĩ tôi đang hỏi? Thêm vào đó, nó là "một cái gì đó giống như" bởi vì tôi không bao giờ có thể làm cho nó hoạt động và phải google xung quanh cho phần xargs.
tooshel

Xin lỗi, nhận xét đó được nhắm vào @ Hello71. Tôi vẫn đang làm quen với nghi thức StackExchange.
geekizard

Hãy xem bài đăng này: theunixshell.blogspot.in/2014/03/ Khăn
Vijay

Câu trả lời:


15
$ find . -type f -print0 | xargs -0 grep foo
$ grep -r foo . # GNU grep only

và ở zshvới setopt extendedglob,

$ grep foo **/*(.)

Tốt hơn:, find . -type f -print0 | xargs -0 grep /dev/null foođể grepluôn in tên tệp phù hợp. Hoặc find . -type f -exec grep /dev/null {} +, đối với các triển khai đã bắt kịp POSIX.2004 (không bao gồm OpenBSD tại thời điểm này).
Gilles 'SO- ngừng trở thành ác quỷ'

Vẫn không thể tin rằng không có cách nào dễ dàng hơn để làm điều này. Và tôi đã thử "grep -r" và nó không hoạt động. Tại sao chỉ có GNU grep và tại sao không có trên nhiều hệ thống?
tooshel

1
Bởi vì truyền thống grepđã không có nó (ý tưởng là nếu bạn muốn đệ quy, bạn sử dụng findvới grep) và thêm nó sau khi thực tế cho hệ thống đã làm việc trong nhiều năm có thể phá vỡ mọi thứ. (GNU grepkhông hoạt động hoàn toàn giống với Hệ thống V. grep)
geekizard

5

Ngoài ra, còn ackđược thiết kế dành riêng cho loại nhiệm vụ này và tự động tìm kiếm thư mục con.


Một đó cũng aglà cách nhanh hơn ack.
mmoya

2

Thay thế cho các find | xargscâu trả lời, bạn có thể cân nhắc sử dụng ctags vì bạn nói rằng bạn đang tìm kiếm không phải văn bản, mà cụ thể là tên hàm.

Để làm điều này, bạn sẽ chạy ctagsvới nguồn của mình để tạo một TAGStệp và sau đó chạy grepvới TAGStệp sẽ nhổ ra các dòng theo định dạng sau:

{tagname}<Tab>{tagfile}<Tab>{tagaddress}

Nơi tagnamesẽ chứa tên hàm, tagfilelà tệp chứa trong đó và tagaddresssẽ là một lệnh vi để đến dòng đó. (Có thể chỉ là một số dòng.)

(Có cách nào dễ dàng để làm điều gì đó tương tự với các chỉ số khác nhau mà nhật thực xây dựng hoặc chỉ truy vấn cơ sở dữ liệu nhật thực không?)


1

Có chuyện gì với grep -r(== grep --recursive)? Am i thiếu cái gì ở đây?

(+1 cho ackquá - Tôi thường xuyên sử dụng cả hai)

chỉnh sửa: Tôi tìm thấy một bài viết tuyệt vời chi tiết các khả năng và cạm bẫy nếu bạn không có GNU grep ở đây . Nhưng, nghiêm túc, nếu bạn không có GNU grepsẵn, việc nhận ackđược thậm chí còn được khuyến khích cao hơn.


Vâng, dường như không phải ai cũng có phiên bản ưa thích của grep.
tooshel

@tooshel - không nhận ra non-GNU grepkhông có tùy chọn đó. đã cập nhật câu trả lời của tôi :)
simon

-bash: ack: lệnh không tìm thấy
tooshel 17/03/2016

Được rồi, tôi đọc hướng dẫn để cài đặt ack. . . và tôi chỉ cần ném nó vào / bin để mọi người có thể sử dụng nó. Đó có phải là một ý tưởng tồi?
tooshel

@tooshel: chỉ khi bạn không muốn mọi người có thể sử dụng nó ...!
simon

0

find . | xargs grep sẽ thất bại trên tên tệp có dấu cách:

> echo test > "a b c"
> find . | xargs grep test
grep: ./a: No such file or directory
grep: b: No such file or directory
grep: c: No such file or directory

Lưu ý rằng ngay cả -print0 có vấn đề này.

Theo ý kiến ​​của tôi, tốt hơn là sử dụng -exec grepvới find sẽ xử lý tất cả tên tệp trong nội bộ và tránh vấn đề này:

> find . -exec grep test {} \;
test
>

1
find … -print0 | xargs -0 …copes với tên tập tin tùy ý. Tất cả các triển khai findcho phép tuân thủ POSIX.2004 find … -exec … {} +, gọi lệnh với nhiều tệp cùng một lúc. Một lệnh tốt hơn là find . -type f -exec grep test /dev/null {} +; việc thêm vào /dev/nulllà như vậy grepsẽ liên tục in tên tệp khi tìm thấy kết quả khớp.
Gilles 'SO- ngừng trở nên xấu xa'


0

$ find -type f -print0 | xargs -r0 grep foo

-rtrong xargsviệc tránh thực thi lệnh nếu không có đầu vào. Đây là một phần mở rộng GNU.

Ngoài ra còn agcó được thiết kế đặc biệt cho điều này và cách tốt hơn ack. Nó có sẵn trong các phiên bản Debian / Ubuntu gần đây trong gói silversearcher-ag .

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.