Tìm một chuỗi con trong các tệp trên các thư mục con với một lệnh dựng sẵn?


10

Trong Windows, nếu tôi muốn tìm một chuỗi trên tất cả các tệp trong tất cả các thư mục con, tôi sẽ làm một cái gì đó như

findstr /C:"the string" /S *.h

Tuy nhiên, trong Linux (ví dụ Ubuntu) Tôi đã tìm thấy không có cách nào khác hơn là một số lệnh đường ống liên quan find, xargsgrep(một ví dụ là tại trang này: ? Làm thế nào tôi có thể đệ quy grep qua thư mục con ). Tuy nhiên, câu hỏi của tôi là khác nhau: có bất kỳ lệnh đơn lẻ, tích hợp nào hoạt động thông qua phép thuật này mà không phải viết kịch bản shell của tôi không?

Câu trả lời:


19

GNU grep cho phép tìm kiếm đệ quy thông qua các thư mục con:

grep -r --include='*.h' 'the string' .

Tôi đã thử dòng lệnh chính xác này trong Ubuntu nhưng nhận được "grep: tùy chọn không hợp lệ - 'M'" mặc dù tôi không thể thấy bất kỳ 'M' nào ở bất cứ đâu ... khó hiểu
Guido Domenici

@Guido Hoạt động tốt ở đây
phunehehe

Trong một chỉnh sửa được đề xuất, TomasG khuyên bạn nên thay đổi lần cuối *thành '*': "Trích dẫn ký tự đại diện cuối cùng là cần thiết để tránh lỗi khi một số tên tệp bắt đầu bằng -"
Michael Mrozek

Trong một vòng xoắn kỳ lạ của sự kiện, bây giờ nó cũng hoạt động với tôi, như được nhập vào câu trả lời ban đầu. Cảm ơn!
Guido Domenici

1
@Guido: Vấn đề của bạn có thể là do một tệp trong thư mục hiện tại được gọi -Msomethinghoặc do GREP_OPTIONScài đặt.
Gilles 'SO- ngừng trở nên xấu xa'

2

grep -r searchpattern /path/to/start/in

Trường hợp /path/to/start/in/có thể chỉ là " ." cho thư mục hiện tại.



0

có cái nào không đơn, tích hợp nào hoạt động thông qua phép thuật này không ...?

Để được mô phạm, không, bạn không thể giả sử một lệnh như vậy tồn tại .

Có rất nhiều cách triển khai Unix khác nhau và mỗi cách đều có những điểm kỳ quặc khác nhau. POSIX, mẫu số chung (và gần nhất với một tiêu chuẩn trên Unices) không chỉ định tùy chọn như vậy chogrep .

Như đã đề cập trong các câu trả lời khác, việc triển khai GNU grep có một tùy chọn không chuẩn, thực hiện những gì bạn muốn. Mặc dù việc triển khai cụ thể này có thể phổ biến trên các hệ thống Linux, nhưng bạn không thể thừa nhận tính khả dụng của nó trên bất kỳ hệ thống Unix nào, ngay cả một số hệ thống Linux.

Cuối cùng, tôi nên đề cập rằng đó là triết lý Unix để ưu tiên sự kết hợp của một số chương trình nguyên thủy, qua việc sử dụng một thực thi nguyên khối lớn cố gắng làm mọi thứ cùng một lúc.

Trong trường hợp của bạn, thu thập dữ liệu hệ thống tệp và kết hợp biểu thức chính quy trong luồng là hai tác vụ riêng biệt. Nó chỉ là bình thường để điều trị mỗi trong một chương trình riêng biệt.


0

Để tìm chuỗi từ thư mục đã cho, sử dụng lệnh bên dưới

find <fullDirectoryPath> -name '*' -exec grep -l '<StringToFind>' {} \;

Ví dụ:

find /apps_bev/apps/xfer/export/02210 -name '*' -exec grep -l '38221000001032' {} \;

1
grepcó thể lấy nhiều hơn một tệp làm đối số, vì vậy bạn nên sử dụng +thay vì \;để tránh chạy một greplời gọi cho mỗi tệp khá kém hiệu quả.
Stéphane Chazelas

1
Lưu ý rằng -name '*'hạn chế các tệp có tên là văn bản hợp lệ trong ngôn ngữ hiện tại ( findít nhất là trong một số triển khai), nhưng các thành phần thư mục khác vẫn có thể chứa các chuỗi byte không tạo thành các ký tự hợp lệ. Nếu ý định của bạn -name '*'là đảm bảo đầu ra là văn bản hợp lệ (bằng cách bỏ qua các tệp có tên không chính xác), bạn nên sử dụng find ... ! -name '*' -prune -o -exec grep ... {} +, điều này cũng sẽ dừng việc findchuyển xuống các thư mục có tên không đúng.
Stéphane Chazelas
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.