Ответы:
Если вы хотите зациклить файлы, никогда не используйте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))
качестве теста. Это очень лаконично. Что касается односложных: если краткость является проблемой, закройте код в функции, тогда не беспокойтесь об этом.
Чтобы удалить все, кроме 3 самых новых файлов, используя глоб zsh, вы можете использовать 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 очень плох.
Этот однострочный делает все, что я думаю:
ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
Вот одно из решений:
rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)