Làm thế nào để chạy find -exec?


Câu trả lời:


710

Bạn đã bỏ lỡ một ;(thoát ở đây \;để ngăn vỏ giải thích nó) hoặc a +và a {}:

find . -exec grep chrome {} \;

hoặc là

find . -exec grep chrome {} +

findsẽ thực thi grepvà sẽ thay thế {}bằng (các) tên tệp được tìm thấy. Sự khác biệt giữa ;+là với ;một greplệnh duy nhất cho mỗi tệp được thực thi trong khi với +càng nhiều tệp càng tốt sẽ được cung cấp làm tham số grepcùng một lúc.


30
Nếu bạn sử dụng \; kết thúc cấu trúc grep được truyền một tệp tại một thời điểm, do đó, nó không hiển thị tên tệp theo mặc định, chỉ có các dòng khớp. Để có được một danh sách tập tin thay vì thêm sử dụng grep -lsbên trong cấu trúc find.
Caleb

9
find . -exec grep foo {} +sẽ hiển thị cho bạn đầu ra như thế này./dir/file.py:from foo import bar
sg

10
find . -exec grep foo {} \;sẽ hiển thị cho bạn đầu ra như thế nàyfrom foo import bar
sg

9
find . -exec grep -l foo {} +sẽ hiển thị cho bạn đầu ra như thế này./dir/file.py
sg

8
find . -exec grep -l foo {} \;sẽ hiển thị cho bạn đầu ra như thế này./dir/file.py
sg

46

Bạn không cần phải sử dụng findcho việc này cả; grep có thể xử lý việc mở các tệp từ danh sách toàn cầu của mọi thứ trong thư mục hiện tại:

grep chrome *

... hoặc thậm chí đệ quy cho thư mục và mọi thứ trong đó:

grep chrome . -R

22
grep sẽ bị sặc nếu việc mở rộng vượt qua ARG_MAX. -R sẽ truy cập mọi thứ trong khi sử dụng find, người ta có thể dễ dàng thêm các nguyên hàm để loại trừ các tệp nhất định (-name, v.v.) hoặc thậm chí không truy cập các cây con (-prune).
Mel

6
Điểm tốt @Mel. Quan điểm của tôi là trong tất cả khả năng, bên hỏi sẽ làm cho mọi thứ trở nên phức tạp hơn mức cần thiết bằng cách giới thiệu findkhi grepcó thể thực hiện công việc, nhưng trong một số trường hợp, sẽ hiệu quả hơn khi sử dụng find để tinh chỉnh danh sách tệp trước khi ra ngoài để grep.
Caleb

4
@Mel grepkhông bị sặc trong trường hợp execnhư vậy.
Chris Xuống

Chỉ hoạt động trong trường hợp tất cả các tệp nằm trong cùng một thư mục, không phải khi chúng được trải rộng trên các thư mục con.
Yaba

1
@Yaba Câu trả lời của tôi nêu cách xử lý trường hợp tệp trải rộng trên các thư mục con.
Caleb

18
find . | xargs grep 'chrome'

bạn cũng có thể làm:

find . | xargs grep 'chrome' -ls

Cái đầu tiên cho bạn thấy các dòng trong các tập tin, thứ hai chỉ liệt kê các tập tin.

Tùy chọn của Caleb gọn gàng hơn, ít tổ hợp phím hơn.


11
Vấn đề với xargslà nó hy vọng đầu vào của nó sẽ được trích dẫn theo một cách đặc biệt mà findkhông sản xuất. Vì vậy, find … | xargs …không hoạt động nếu bạn có tên tệp chứa khoảng trắng hoặc \'".
Gilles

3
@Gilles Bạn có thể khắc phục vấn đề đó bằng cách sử dụng một cái gì đó giống như find . | xargs -n1 -iX grep "X" 'chrome'vậy để các đối số được đưa ra cùng một lúc và được trích dẫn. Rõ ràng đây là một cách không hiệu quả khủng khiếp để xử lý ví dụ này, nhưng đối với một số tình huống thì thật tuyệt.
Caleb

Để hoàn thiện, chúng ta cũng nên đề cập đến tùy chọn -i cho trường hợp không nhạy cảm với 'grep'. Ngoài ra còn có -iname trong tìm kiếm cho trường hợp không nhạy cảm.
Mathew

9
@Caleb: Cách duy nhất đáng tin cậy 100% để xargsđối phó với tên tệp Linux là find ... -print0 | xargs -0sử dụng NUL làm dấu phân tách. Thay thế - xargs -d '\n'sử dụng dòng mới làm dấu phân tách, độ tin cậy 99%.
grawity

Tôi sử dụng điều này thường xuyên, nhưng nó sẽ thất bại trong danh sách tên tệp rất dài, tại thời điểm đó, find -exec trở thành người chiến thắng.
Spacemoose

5

Tìm là một cách và bạn có thể thử the_silver_searchersau đó tất cả những gì bạn cần làm là

ag chrome

Nó sẽ tìm kiếm chrome trong tất cả các tệp (bao gồm các thư mục phụ) và nó nhanh hơn tìm thấy


Ngoài ra còn có pt (trình tìm kiếm bạch kim, có sẵn tại github.com/monochromegane/the_platinum_searcher ), IMHO, thực hiện công việc nhanh hơn - có thể không quan trọng nếu chỉ có một vài tệp.
Nhảy Bunny

1

Để xem danh sách các tập tin thay vì dòng:

grep -l "chrome" *

hoặc là:

grep -r -l "chrome" .

1

Đây là một ví dụ về cách tôi thường sử dụng find / exec ...

find  . -name "*.py" -print -exec fgrep hello {} \;

Tìm kiếm này đệ quy cho tất cả các tệp .py và cho mỗi tệp in ra tên tệp và fgrep 'cho' xin chào 'trên tệp đó (cho mỗi tệp). Đầu ra trông giống như (vừa chạy một ngày hôm nay):

./r1.py
./cgi-bin/tst1.py
print "hello"
./app/__init__.py
./app/views.py
./app/flask1.py
./run.py
./tst2.py
print "hello again"

1
không gây rối với quy trình làm việc của bạn, nhưng bạn có thể thích: find . -name "*.py" -exec fgrep -l hello {} \; - nó sẽ in tên tệp của các tệp trùng khớp và không có gì khác
Jeff Schaller
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.