Ok, hãy áp dụng triết lý unix. Các thành phần của nhiệm vụ này là gì?
- Tìm kiếm văn bản: bạn cần một công cụ để tìm kiếm văn bản trong một tệp, chẳng hạn như
grep
.
- Đệ quy: bạn cần một công cụ để tìm kiếm các tệp trong cây thư mục, chẳng hạn như
find
.
- Lưu trữ: bạn cần một công cụ để đọc chúng.
Hầu hết các chương trình unix hoạt động trên các tập tin. Vì vậy, để hoạt động dễ dàng trên các thành phần lưu trữ, bạn cần truy cập chúng dưới dạng tệp, nói cách khác, bạn cần truy cập chúng dưới dạng thư mục.
Hệ thống tệp AVFS trình bày một khung nhìn của hệ thống tệp trong đó mọi tệp lưu trữ /path/to/foo.zip
có thể truy cập dưới dạng một thư mục ~/.avfs/path/to/foo/zip#
. AVFS cung cấp quyền truy cập chỉ đọc vào hầu hết các định dạng tệp lưu trữ phổ biến.
mountavfs
find ~/.avfs"$PWD" \( -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
-exec sh -c '
find "$0#" -name "*.pm" -exec grep "$1" {\} +
' {} 'Test::Version' \;
fusermount -u ~/.avfs # optional
Giải thích:
- Gắn kết hệ thống tập tin AVFS.
- Tìm tệp lưu trữ trong
~/.avfs$PWD
, đó là dạng xem AVFS của thư mục hiện tại.
- Đối với mỗi kho lưu trữ, hãy thực thi đoạn mã được chỉ định (với
$0
= tên lưu trữ và $1
= mẫu để tìm kiếm).
$0#
là giao diện thư mục của kho lưu trữ $0
.
{\}
thay vì {}
cần thiết trong trường hợp các find
thay thế bên ngoài {}
bên trong các -exec ;
đối số (một số làm điều đó, một số thì không).
- Tùy chọn: cuối cùng ngắt kết nối hệ thống tập tin AVFS.
Hoặc trong zsh ≥4.3:
mountavfs
grep 'Test::Version' ~/.avfs$PWD/**/*.(tgz|tar.gz|zip)(e\''
reply=($REPLY\#/**/*.pm(.N))
'\')
Giải thích:
~/.avfs$PWD/**/*.(tgz|tar.gz|zip)
phù hợp với tài liệu lưu trữ trong chế độ xem AVFS của thư mục hiện tại và các thư mục con của nó.
PATTERN(e\''CODE'\')
áp dụng MÃ cho mỗi trận đấu của THỰC HIỆN. Tên của tệp phù hợp là trong $REPLY
. Đặt reply
mảng biến trận đấu thành một danh sách các tên.
$REPLY\#
là giao diện thư mục của kho lưu trữ.
$REPLY\#/**/*.pm
phù hợp với .pm
các tập tin trong kho lưu trữ.
- Vòng
N
loại toàn cầu làm cho mô hình mở rộng thành một danh sách trống nếu không có kết quả khớp.