Hãy nói rằng tôi có một thư mục ḟoo/
chứa rất nhiều tệp trong một số loại cấu trúc thư mục. Tôi cần phải giữ một số trong số họ, nhưng không phải tất cả.
Có cách nào (tại chỗ) xóa tất cả chúng ngoại trừ (nói) 500 mới nhất không?
Hãy nói rằng tôi có một thư mục ḟoo/
chứa rất nhiều tệp trong một số loại cấu trúc thư mục. Tôi cần phải giữ một số trong số họ, nhưng không phải tất cả.
Có cách nào (tại chỗ) xóa tất cả chúng ngoại trừ (nói) 500 mới nhất không?
Câu trả lời:
Tôi làm nhiệm vụ này thường xuyên, và tôi sử dụng các biến thể sau đây. Đó là một đường ống kết hợp các công cụ đơn giản khác nhau: Tìm tất cả các tệp, thêm trước thời gian sửa đổi tệp, sắp xếp, xóa thời gian sửa đổi tệp, hiển thị tất cả các dòng trừ 500 đầu tiên và xóa chúng:
find foo/ -type f | perl -wple 'printf "%12u ", (stat)[9]' | \
sort -r | cut -c14- | tail -n +501 | \
while read file; do rm -f -- "$file"; done
Một vài bình luận:
Nếu bạn đang sử dụng tập tin bash trực tiếp, bạn nên sử dụng tập tin đọc -r, và không chỉ tập tin đọc tập tin.
Sử dụng một cách nhanh chóng để xóa các tệp tin nhanh hơn (và cũng xử lý các ký tự kỳ lạ trong các tên tập tin tốt hơn so với vòng lặp while, trừ khi bạn đang sử dụng tập tin đọc -r tập tin)
... | tail -n +501 | perl -wnle 'unlink() or warn "$_: unlink failed: $!\n"'
Một số phiên bản của đuôi đuôi Cameron không hỗ trợ tùy chọn của cải tiến, vì vậy bạn phải sử dụng đuôi đuôi +501. Một cách di động để bỏ qua 500 dòng đầu tiên là
... | perl -wnle 'print if $. > 500' | ...
Nó sẽ không hoạt động nếu tên tệp của bạn chứa dòng mới.
Nó không yêu cầu GNU tìm.
Kết hợp những điều trên mang đến cho bạn:
find foo/ -type f | perl -wple 'printf "%12u ", (stat)[9]' | \
sort -r | cut -c14- | perl -wnle 'print if $. > 500' | \
perl -wnle 'unlink() or warn "$_: unlink failed: $!\n"'
Đây là cách tôi sẽ làm điều đó trong Python 3. Nó cũng sẽ hoạt động cho các HĐH khác. Sau khi kiểm tra điều này, hãy đảm bảo bỏ ghi chú dòng thực sự loại bỏ các tệp.
import os,os.path
from collections import defaultdict
FILES_TO_KEEP = 500
ROOT_PATH = r'/tmp/'
tree = defaultdict(list)
# create a dictionary containing file names with their date as the key
for root, dirs, files in os.walk(ROOT_PATH):
for name in files:
fname = os.path.join(root,name)
fdate = os.path.getmtime( fname )
tree[fdate].append(fname)
# sort this dictionary by date
# locate where the newer files (that you want to keep) end
count = 0
inorder = sorted(tree.keys(),reverse=True)
for key in inorder:
count += len(tree[key])
if count >= FILES_TO_KEEP:
last_key = key
break
# now you know where the newer files end, older files begin within the dict
# act accordingly
for key in inorder:
if key < last_key:
for f in tree[key]:
print("remove ", f)
# uncomment this next line to actually remove files
#os.remove(f)
else:
for f in tree[key]:
print("keep ", f)
Tôi không biết về "500 mới nhất", nhưng với tìm kiếm, bạn có thể xóa những thứ cũ hơn X phút / ngày. Ví dụ cho tệp và cũ hơn 2 ngày:
find foo/ -mtime +2 -a -type f -exec rm -fv \{\} \;
Thử nghiệm đầu tiên với:
find foo/ -mtime +2 -a -type f -exec ls -al \{\} \;
Lưu ý dấu gạch chéo ngược và khoảng trắng trước "\;". Xem trang tìm người để biết thêm.
Tại sao không sử dụng mã đơn giản hơn này:
$ ls -t1 foo/| xargs -d '\n' rm --
rm -f
mặc dù.