Câu trả lời:
Nếu bạn muốn lặp qua các tập tin, không bao giờ sử dụngls
*. tl; dr Có rất nhiều tình huống cuối cùng bạn xóa tệp sai hoặc thậm chí tất cả các tệp.
Điều đó nói rằng, thật không may, đây là một điều khó khăn để làm ngay trong Bash. Có một câu trả lời làm việc tại một câu hỏi trùng lặp thậm chí cũ hơnfind_date_sorted
mà bạn có thể sử dụng với các sửa đổi nhỏ:
counter=0
while IFS= read -r -d '' -u 9
do
let ++counter
if [[ counter -gt 3 ]]
then
path="${REPLY#* }" # Remove the modification time
echo -e "$path" # Test
# rm -v -- "$path" # Uncomment when you're sure it works
fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p\0' | sort -rz) # Find and sort by date, newest first
* Không có kẻ xúc phạm - Tôi cũng đã sử dụng ls
trước đây. Nhưng nó thực sự không an toàn.
Chỉnh sửa: Mớifind_date_sorted
với các bài kiểm tra đơn vị.
((++counter>3))
làm bài kiểm tra của bạn. Nó gọn gàng độc đáo. Đối với oneliners: Nếu sự ngắn gọn là một mối quan tâm bao bọc mã trong một hàm, thì đừng lo lắng về nó.
Để xóa tất cả trừ 3 tệp mới nhất bằng zsh global, bạn có thể sử dụng Om
(viết hoa O) để sắp xếp các tệp từ cũ nhất đến mới nhất và một chỉ mục để lấy các tệp bạn muốn.
rm ./*(Om[1,-4])
# | |||| ` stop at the 4th to the last file (leaving out the 3 newest)
# | |||` start with first file (oldest in this case)
# | ||` subscript to pick one or a range of files
# | |` look at modified time
# | ` sort in descending order
# ` start by looking at all files
Những ví dụ khác:
# delete oldest file (both do the same thing)
rm ./*(Om[1])
rm ./*(om[-1])
# delete oldest two files
rm ./*(Om[1,2])
# delete everything but the oldest file
rm ./*(om[1,-2])
Cho đến nay, phương pháp đơn giản nhất là sử dụng zsh và vòng loại toàn cầu của nó : Om
sắp xếp theo độ tuổi giảm (tức là già nhất trước) và [1,3]
chỉ giữ lại ba trận đấu đầu tiên.
rm ./*(Om[1,3])
Xem thêm Làm thế nào để tôi lọc một quả cầu trong zsh để biết thêm ví dụ.
Và hãy chú ý lời khuyên của l0b0 : mã của bạn sẽ bị hỏng khủng khiếp nếu bạn có tên tệp chứa các ký tự đặc biệt.
Bạn có thể sử dụng chức năng sau để lấy tệp mới nhất trong một thư mục:
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
Cung cấp cho nó một tập hợp các tệp khác nhau bằng cách loại bỏ tệp mới nhất sau mỗi lần lặp.
Mẹo: Nếu bạn giữ tập hợp tệp ban đầu trong một mảng có tên là "$ {files [@]}", thì hãy lưu chỉ mục của tệp mới nhất được tìm thấy và unset 'files[index]'
trước lần lặp tiếp theo.
Sử dụng: newest_in [set of files/directories]
Đầu ra mẫu:
[rany$] newest_in ./*
foo.txt
[rany$]
Đầu tiên, -R
tùy chọn dành cho đệ quy, có lẽ không phải là điều bạn muốn - điều đó cũng sẽ tìm kiếm trong tất cả các thư mục con. Thứ hai, <
toán tử (khi không được xem là chuyển hướng) là để so sánh chuỗi. Bạn có thể muốn -lt
. Thử:
while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
Nhưng tôi sẽ sử dụng tìm ở đây:
while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
Tôi biết đó là một tội lỗi để phân tích ls
, nhưng những gì về điều này:
find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm
Một thử nghiệm nhanh với 5 tệp trống:
$ >1
$ >2
$ >3
$ >4
$ >5
$ find . -type f -maxdepth 1 | xargs ls -lt | sed '1,3d' | awk '{print $9}' | xargs rm
$ ls -1
3
4
5
ls
đầu ra và sử dụng find
và xargs
cùng nhau sai cách. Nếu bạn kết hợp find
và xargs
tôi khuyên bạn nên sử dụng tùy chọn find
s -print0
và theo xargs
đó -O
. Đọc về Sử dụng Tìm để biết thêm thông tin về chủ đề. Bạn cũng có thể muốn xem và đọc về lý do tại sao Parsing ls rất tệ.
Điều này một lót làm tất cả những gì tôi nghĩ:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
Đây là một giải pháp:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)