Bạn có thể sử dụng globalstar.
Với globstar
tùy chọn shell được kích hoạt, tất cả những gì bạn cần là gzip -vk **/*.{css,html}
.
Các Bash shell có một globstar
tùy chọn cho phép bạn viết đệ quy globs với **
. shopt -s globstar
cho phép nó. Nhưng bạn có thể không muốn làm điều đó cho các lệnh khác mà bạn chạy sau đó, vì vậy bạn có thể chạy nó và gzip
lệnh của bạn trong một lớp con thay thế.
Lệnh này gzip
là tất cả .css
và .html
các tệp trong thư mục hiện tại bất kỳ thư mục con nào, bất kỳ thư mục con nào của chúng , v.v., giữ các tệp gốc ( -k
) và cho bạn biết nó đang làm gì ( -v
):
(shopt -s globstar; gzip -vk **/*.{css,html})
Nếu bạn muốn khớp tên tệp không phân biệt chữ hoa chữ thường để các phần mở rộng có một số hoặc tất cả các chữ cái viết hoa được bao gồm, thì bạn cũng có thể bật nocaseglob
tùy chọn shell:
(shopt -s globstar nocaseglob; gzip -vk **/*.{css,html})
;
tách hai lệnh và bên ngoài (
)
khiến chúng được chạy trong một lớp con. Đặt tùy chọn shell trong subshell không khiến nó được đặt trong shell gọi. Nếu bạn làm muốn kích hoạt globstar
sau đó bạn có thể chạy shopt -s globstar
; sau đó bạn có thể chạy lệnh:
gzip -vk **/*.{css,html}
Bạn có thể vô hiệu hóa globstar
với shopt -u globstar
. Bạn có thể kiểm tra nếu nó hiện được kích hoạt với shopt globstar
.
Làm thế nào nó hoạt động
Chìa khóa để làm thế nào gzip
lệnh này hoạt động là shell thực hiện các mở rộng trên nó để tạo ra một danh sách của mỗi tệp trong hệ thống phân cấp thư mục với một tên phù hợp, sau đó chuyển từng tên tệp này làm đối số gzip
.
- Niềng răng mở rộng biến
**/*.{css,html}
thành **/*.css **/*.html
.
- Sau đó, globalbing mở rộng hai mẫu đó thành tên của các tệp có thể truy cập trong thư mục hiện tại (
**
do globstar
) tên tệp của nó bao gồm mọi thứ ( *
) theo sau là hậu tố được chỉ định ( .css
hoặc .html
trong trường hợp này).
Điều này không khớp với các tệp có tên bắt đầu bằng.
hoặc các tệp nằm trong các thư mục được đặt tên theo cách này. Bạn có thể không có bất kỳ tệp HTML và CSS nào như vậy và nếu có, bạn có thể không muốn bao gồm chúng. Nhưng nếu bạn muốn bao gồm chúng, thì bạn có thể kết hợp chúng rõ ràng tùy thuộc vào nhu cầu của bạn. Ví dụ: thay đổi **/*.{css,html}
để **/{,.}*.{css,html}
bao gồm các tệp bắt đầu .
trong khi vẫn không tìm kiếm trong các thư mục.
Nếu bạn muốn cả hai tệp có tên bắt đầu .
và tệp trong thư mục có tên bắt đầu .
được bao gồm, có một cách đơn giản và đơn giản hơn: bật dotglob
tùy chọn shell.
(shopt -s globstar dotglob; gzip -vk **/*.{css,html})
Hoặc nếu bạn muốn kết hợp không phân biệt chữ hoa chữ thường và khớp tên tệp bắt đầu bằng .
:
(shopt -s globstar nocaseglob dotglob; gzip -vk **/*.{css,html})
Mặc dù rất hiếm khi có **
thể mở rộng sang thứ gì đó quá lâu.
Nếu bạn có một số lượng lớn tệp được đặt tên theo cách này, thì điều này có thể thất bại với thông báo lỗi giải thích rằng trình bao không thể xây dựng dòng lệnh vì nó sẽ quá dài. (Ngay cả với hàng ngàn tệp, điều này thường không phải là vấn đề.)
gzip
sẽ không được gọi gì cả, vì vậy bạn sẽ không có được một công việc nửa vời.
Nếu lỗi này xảy ra, hoặc nếu bạn lo lắng về nó, bạn có thể sử dụng find
với -exec
, như mô tả thép (với {} \;
) hoặc như tôi mô tả bên dưới (với {} +
).
Bạn có thể sử dụng find
với các -exec
hành động và +
cho hiệu quả.
Các gzip
hỗ trợ lệnh được đưa ra tên của nhiều file được nén. Nhưng find
lệnh này , mặc dù nó hoạt động tốt và sẽ không bị chậm trừ khi bạn có nhiều tệp, chạy gzip
lệnh một lần cho mỗi tệp:
find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} \;
Điều này hoạt động, và bạn chắc chắn có thể sử dụng nó. ( .
tìm kiếm từ thư mục hiện tại. Bên cạnh đó, đó thực sự là một cách viết lệnh hơi khác trong câu trả lời rất hay của Steeldo ; bạn có thể sử dụng bất kỳ kiểu nào bạn thích.)
Bạn cũng có thể find
chuyển nhiều tên tệp đến gzip
và chạy nó nhiều lần nếu cần - gần như luôn luôn chỉ một lần. Để làm điều đó, sử dụng +
thay vì\;
. Cuộc +
tranh cãi sẽ đến ngay sau đó {}
. find
thay thế +
bằng tên tệp bổ sung, nếu có.
find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +
Bạn có thể sử dụng +
ngay cả khi chỉ có một vài tệp phù hợp và khi có nhiều tệp trong số đó, có thể nhanh hơn đáng kể so với việc có một lệnh gzip
gọi riêng cho mỗi tệp.
Như Steeldo đề cập , bạn có thể sử dụng -iname
thay vì -name
khớp các tệp có tên kết thúc giống .css
hoặc .html
với cách viết hoa khác nhau. Điều này tương ứng với việc kích hoạt nocaseglob
trong globstar
phương pháp dựa trên mô tả ở trên.
Cuối cùng, bạn có thể không có bất kỳ tệp hoặc thư mục phù hợp nào bắt đầu bằng .
. Nhưng nếu bạn làm, find
tự động bao gồm chúng. Nếu bạn muốn loại trừ chúng (như xảy ra với globstar
phương pháp dựa trên chi tiết ở trên khi dotglob
tắt), bạn có thể :
find . -not -path '*/.*' \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +
Cách globstar
dựa trên mô tả ở trên đơn giản hơn để viết, đặc biệt nếu bạn loại trừ các thư mục và tệp bắt đầu .
, vì đó là mặc định.
Có gì không để làm ...
Tên tệp có thể chứa bất kỳ ký tự nào ngoại trừ dấu phân cách đường dẫn /
và ký tự null . Nhiều kỹ thuật phá vỡ tên tập tin kỳ lạ tồn tại và chúng thường phức tạp hơn các kỹ thuật luôn chỉ hoạt động. Vì vậy, tôi khuyên bạn nên tránh chúng ngay cả khi bạn biết (hoặc nghĩ rằng bạn biết) họ vẫn ổn trong tình huống cụ thể của bạn. Và tất nhiên bạn phải không sử dụng chúng nếu bạn có thể có tên tập tin với các nhân vật có thể được điều trị đặc biệt, bao gồm cả khoảng trắng.
Có thể chuyển một cách an toàn đầu ra của find
một lệnh khác xử lý nó nếu bạn sử dụng -print0
hoặc một hành động tương tự để khiến nó đặt ký tự null giữa các đường dẫn thay vì một dòng mới , và ngược lại. Tên tệp có thể chứa dòng mới (mặc dù tôi không khuyến khích bạn cố tình đặt tên tệp với chúng). Một find
lệnh có -print
hành động - bao gồm các lệnh find không có hành động rõ ràng, do đó -print
là mặc định - không tạo ra đầu ra có thể được dẫn một cách an toàn hoặc được cung cấp cho một lệnh khác thực hiện một hành động trên các tệp.
Đầu ra find
tạo ra với -print0
hành động có thể được dẫn đến một cách an toàn xargs -0
( -0
cờ cho biết xargs
đầu vào được phân tách bằng null).
-r
làm việc theo thiết kế. Từ man gzip : Du lịch cấu trúc thư mục đệ quy. Nếu bất kỳ tên tệp nào được chỉ định trên dòng lệnh là thư mục , gzip sẽ xuống thư mục và nén tất cả các tệp mà nó tìm thấy ở đó (hoặc giải nén chúng trong trường hợp gunzip). (nhấn mạnh của tôi)