Làm cách nào tôi có thể grep kết quả TÌM bằng cách sử dụng -EXEC và vẫn xuất ra tệp?


64

Tốt hơn để giải thích về các ví dụ.

Tôi có thể:

find . -name "*.py" -type f > output.txt

Nhưng làm thế nào tôi có thể lưu trữ đầu ra vào cùng một tệp cho:

find . -name "*.py" -type f -exec grep "something" {} \

Tôi không thể làm

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt

Câu trả lời:


105

Nếu tôi hiểu bạn chính xác thì đây là những gì bạn muốn làm:

find . -name '*.py' -print0 | xargs -0 grep 'something' > output.txt

Findtất cả các tệp có phần mở rộng py, grepchỉ các hàng có chứa somethingvà lưu các hàng trong đó output.txt. Nếu tập tin chứa bất cứ điều gì nó sẽ được thay thế.

Chỉnh sửa: Sử dụng -exec:

find . -name '*.py' -exec grep 'something' {} \; > output.txt

Tôi đang kết hợp bình luận của Chris Downs ở đây. Lệnh trên sẽ dẫn đến grepviệc được thực thi nhiều lần khi findtìm thấy sự xuất hiện. Tuy nhiên, nếu bạn thay thế ;bằng a +, grepđược gọi bằng đầu ra từ findnối (đến một giới hạn nhất định). Xem câu hỏi Sử dụng dấu chấm phẩy (;) so với dấu cộng (+) với exec trong find để tìm hiểu thêm về chủ đề.


16
Sử dụng +thay vì \;, nó sẽ cải thiện đáng kể thời gian thực hiện (vì nó sẽ chống lại các đối số trước khi thực hiện cho đến khi ARG_MAX).
Chris Xuống

Bây giờ tôi hiểu sức mạnh của xargs! Cảm ơn!
domih

4
Sử dụng grep -Hnếu bạn muốn bao gồm tên tệp của tệp trong đầu ra.
Steinar

18

Nếu bạn muốn lưu tất cả các dòng phù hợp trên tất cả các tệp trong output.txt, lệnh cuối cùng của bạn sẽ hoạt động, ngoại trừ việc bạn thiếu yêu cầu ;ở cuối lệnh.

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt

Nếu bạn muốn mỗi lần chạy grepđể tạo đầu ra cho một tệp khác nhau, hãy chạy shell để tính tên tệp đầu ra và thực hiện chuyển hướng.

find . -name "*.py" -type f -exec sh -c 'grep "something" <"$0" >"$0.txt"' {} \;

cái cuối cùng thực sự tốt đẹp: D
bakytn

Để mở rộng câu trả lời @gilles để làm cho nó có nhiều thông tin hơn, đặc biệt nếu danh sách các tệp bạn đang xử lý lớn, bạn có thể báo cáo tên tệp (đường dẫn tương đối) của mỗi tệp cùng với kết quả được xác định bằng cách sử dụng : find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt Và nếu bạn muốn xem số dòng của các dòng đã được chỉnh sửa, dĩ nhiên, bạn có thể sử dụnggrep -n "something"
JJMpls

9

Đối với bản ghi, grep--includevà các --excludeđối số mà bạn có thể sử dụng để lọc các tệp mà nó tìm kiếm:

grep -r --include="*.py" "something" > output.txt

2
Ít nhất là GNU grep.
phk

2

Sử dụng tee:

find . -name '*.py' | tee output.txt | xargs grep 'something'

Thông báo trước là nếu bạn có bất kỳ tệp nào có ký tự đặc biệt (bao gồm khoảng trắng) xargsgrepsẽ không hoạt động tốt với ( a file.txtsẽ được hiểu là hai tệp afile.txt). Thay thế cho điều đó là sử dụng -xhoặc -print0, nhưng một trong hai sẽ gây ô nhiễm cho bạn output.txt. Các -xsẽ sử dụng \để thoát khỏi một số ký tự đặc biệt và điều này sẽ được trong output.txt. Các -print0sẽ sử dụng một byte null như một tách lĩnh vực (mà cũng đòi hỏi xargs -0) và output.txtsẽ trông giống như một dòng tiếp giáp dài của văn bản.

Làm thế nào bạn đối phó (hoặc không) với điều này là tùy thuộc vào bạn.

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.