Відповіді:
Якщо ви хочете перебирати файли, ніколи не використовуйтеls
*. tl; dr Є багато ситуацій, коли ви в кінцевому підсумку видалите неправильний файл або навіть усі файли.
Це сказало, на жаль, це хитра річ зробити правильно в Bash. Там у відповідь працює над у вигляді дубліката питання мого навіть старшеfind_date_sorted
, які ви можете використовувати з невеликими змінами:
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
* Хлопці без образи - я також використовував ls
раніше. Але це насправді не безпечно.
Правка: Новеfind_date_sorted
з одиничними тестами.
((++counter>3))
як ваш тест. Це приємно лаконічно. Що стосується oneliners: Якщо стислість - це питання, загорніть код у функцію, тоді не турбуйтеся про це.
Щоб видалити всі, крім трьох найновіших файлів, за допомогою zsh glob, ви можете використовувати Om
(з великої літери O) для сортування файлів від найдавніших до найновіших та підрозділу, щоб захопити потрібні файли.
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
Інші приклади:
# 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])
На сьогодні найпростішим методом є використання zsh та його глобальних класифікаторів : Om
сортування за зменшенням віку (тобто найстарішого першого) та [1,3]
збереження лише перших трьох матчів.
rm ./*(Om[1,3])
Дивіться також Як я фільтрую глобус у zsh для отримання додаткових прикладів.
І дотримуйтесь порад l0b0 : ваш код жахливо зламається, якщо у вас є імена файлів, які містять спеціальні символи оболонки.
Ви можете використовувати таку функцію, щоб отримати найновіший файл у каталозі:
newest_in()
{
local newest=$1
for f;do [[ $f -nt $newest ]] && newest="$f"; done;
printf '%s\n' "$newest"
}
Надайте йому інший набір файлів, вилучаючи найновіший файл після кожної ітерації.
Порада: Якщо ви тримаєте початковий набір файлів у масиві під назвою "$ {files [@]}", тоді збережіть індекс найновішого знайденого файлу та unset 'files[index]'
до наступної ітерації.
Використання: newest_in [set of files/directories]
Вибірка зразка:
[rany$] newest_in ./*
foo.txt
[rany$]
По-перше, це -R
варіант для рекурсії, яка, мабуть, не є тим, що ви хочете - що буде шукати і у всіх підкаталогах. По-друге, <
оператор (коли не сприймається як перенаправлення) призначений для порівняння рядків. Ви, мабуть, хочете -lt
. Спробуйте:
while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
Але я б застосував пошук тут:
while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
Я знаю, що гріх розбирати ls
, але що з цього приводу:
find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm
Швидкий тест з 5 порожніми файлами:
$ >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
виведення та використання find
та xargs
неправильне використання разом. Якщо об'єднати find
і xargs
я рекомендую вам використовувати find
s -print0
і відповідно xargs
S -O
варіантів. Прочитайте про використання Find для отримання додаткової інформації про цю тему. Ви також можете поглянути і почитати про те, чому Парсінг Лс дуже поганий.
Цей одноколісний робить все, що я думаю:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
Ось одне рішення:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)