Unix 'grep' cho một chuỗi trong tất cả các tệp gzip trong tất cả các thư mục con


8

Làm cách nào để grep cho một chuỗi đệ quy thông qua tất cả .gzcác tệp trong tất cả các thư mục và thư mục con?

Câu trả lời:


13

@Steve Weet gần như ở đó. Việc sử dụng / dev / null làm đối số bổ sung là một cách hay để buộc tên tệp được hiển thị (tôi sẽ nhớ điều đó, cảm ơn Steve) nhưng nó vẫn chạy tệp thực thi cho mọi tệp được tìm thấy - một chi phí rất lớn.

Bạn muốn chạy zgrep ít nhất có thể, tận dụng tối đa mỗi lần thực hiện:

find . -iname '*.gz' -print0 | xargs -0 zgrep PATTERN

xargssẽ cung cấp càng nhiều đối số (tên tệp) càng tốt cho zgrep và liên tục thực thi nó cho đến khi nó sử dụng tất cả các tệp được cung cấp bởi findlệnh. Sử dụng các tùy chọn -print0-0cho phép nó hoạt động nếu có khoảng trắng trong bất kỳ tên tệp hoặc thư mục nào.

Trên Mac OS X, bạn có thể đạt được hiệu ứng tương tự mà không cần xargs:

find . -iname '*.gz' -exec zgrep PATTERN {} +

+1 Điều đó thực sự tốt đẹp. Tôi đã không nhận ra rằng xargs đã vượt qua nhiều hơn một đối số. Phần lớn dòng lệnh * nix của tôi đã 20 tuổi và tôi không nghĩ rằng xargs đã làm điều đó 20 năm trước.
Steve Weet

Hóa ra là tìm thấy trên os / x hoạt động giống như xargs
Steve Weet

1
Xem nhận xét của tôi về câu trả lời của Steve Weet về kết thúc '+' cho -exec.
Daniel Andersson

Sử dụng -Hđể luôn hiển thị tên tệp với dòng phù hợp, trong GNU grep ít nhất.
Daniel Andersson

1
$ zgrep --help
Usage: /bin/zgrep [OPTION]... [-e] PATTERN [FILE]...
Look for instances of PATTERN in the input FILEs, using their
uncompressed contents if they are compressed.

Vì vậy, một cái gì đó như

find . -iname "*.gz" -exec zgrep PATTERN {} \

-Exec sẽ sinh ra một phiên bản mới của zgrep cho mỗi tệp mà nó lặp đi lặp lại ngăn bạn nhìn thấy tên tệp. Sẽ tốt hơn nếu sử dụng zgrep -rđể đi qua một cái cây hoặc nếu -r không hoạt động, dẫn đầu ra của tìm kiếm thông quaxargs zgrep
Noufal Ibrahim

Tôi nhận được /bin/zgrep: -r: option not supportedtrên hệ thống Ubuntu mới cài đặt của tôi.
aioobe

Bạn có thể sử dụng xargsthay thế sau đó.
Noufal Ibrahim

Xem nhận xét của tôi về câu trả lời của Steve Weet về kết thúc '+' cho -exec.
Daniel Andersson

1

@aioobe gần hết rồi. Lệnh sẽ thực hiện công việc nhưng sẽ không cho bạn biết tên tệp

Sau đây sẽ cho bạn biết tên tệp là:

find . -iname "*.gz" -exec zgrep PATTERN {} /dev/null \;

Việc thêm vào /dev/nullsẽ đảm bảo zgrep nhìn thấy hai tên tệp để nó hiển thị cho bạn tên của tệp nếu tìm thấy chuỗi

BIÊN TẬP

Nghiên cứu sâu hơn cho thấy rằng đối với máy của tôi (OS / X), -execđối số cần tìm sẽ thêm càng nhiều tên tệp càng tốt (tương tự như cách xargsứng xử).


Điều đó thật tuyệt, tôi không biết điều đó về OSX -exec- Tôi hoàn toàn nói về tính di động nên tôi sẽ không sử dụng nó trong một tập lệnh, nhưng tuyệt vời cho dấu nhắc lệnh.

Đối với các phiên bản tìm kiếm khác, sử dụng '+' thay vì '\;' để kết thúc câu lệnh exec sẽ làm tương tự như OSX, bởi các câu chuyện trong luồng này, theo mặc định. Xem mục nhập thủ công cho lệnh '-exec {} +'. Điều này không đúng với tất cả các phiên bản find, nhưng hầu hết các phiên bản hiện đại (ví dụ như trong các bản phân phối dựa trên Debian).
Daniel Andersson

Sử dụng -Hđể luôn hiển thị tên tệp với dòng phù hợp, ít nhất là trong GNU grep, thay vì /dev/nullhack.
Daniel Andersson

0

Sau đây là một điều trị trong zsh

for archive in **/*.gz; do
    echo "[${archive}] "
    gzip -dc ${archive} | grep -n "String"
done

Nó cũng có thể làm việc trong bash, ksh, vv ...

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.