7

Я ищу скрипт Bash, который войдет в список каталогов и удалит все, кроме четырех самых последних созданных файлов.

Как я могу это сделать?

5 ответов5

6
ls -t | sed '1,4d' | xargs echo rm

Удалите echo когда вы удовлетворены, это результат, который вы хотите.

Если у вас есть имена файлов с пробелами, требуется больше работы.

0

Вы хотите сохранить четыре самых последних файла в каждом каталоге или четыре самых последних файла в ЛЮБОМ каталоге?

Чтобы решить первую проблему, вы должны использовать find, чтобы перечислить каждый каталог, а затем удалить из него все, кроме четырех самых последних файлов. Это не так уж сложно.

Чтобы решить вторую проблему, нужно немного подумать, но на самом деле ее легче написать.

По сути, найти каждый файл рекурсивно. Вызовите команду "stat", возвращающую время и имя модификации файла. Отсортируйте это по убыванию и пропустите первые четыре файла, которые являются самыми последними.

Затем удалите ведущие метки времени и удалите результирующий список имен файлов.

Что-то вроде (не проверено):

#!/bin/bash

find "$@" -type f -print0 \
| xargs -0 stat -c$'%Y\t%n' \
| sort -rn \
| awk -F$'\t' 'NR > 4 {print $2}' \
| while read f; do
    echo rm -v "${f}"
  done

Это должно сработать, хотя вы захотите убрать 'echo' в цикле while, чтобы сделать его эффективным. Сначала проверьте это внимательно!

0

Я понимаю, что это не совсем то, о чем вы просите, но для такого вида резервного копирования я предпочитаю вращать файлы журналов перед созданием нового. Это немного более явно, и намного проще для кода, как это:

#!/bin/bash

#Archive old backups
move () {
  if [ -e $1 ]
  then
    echo "Archiving old backups: $1 to $2"
    mv -f $1 $2 || echo "FAILED"
  fi
}

#Bump each backup +1
rm -rf backup.4
move backup.3.tgz backup.4.tgz
move backup.2.tgz backup.3.tgz
move backup.1.tgz backup.2.tgz
move backup.tgz backup.1.tgz

#Now create today's backup
...
0

Эта команда должна работать

find PATH1 PATH2 PATH3 -type f  -printf '%T@ %p\n'|sort -nr|tail -n+5|cut -f 2- -d " "|xargs -i rm {}

Если вы не хотите, чтобы команда рекурсивно удаляла файлы, добавьте опцию -maxdepth 1 перед -type -type f

Команда рекурсивно печатает каждый файл с его последней датой изменения (find PATH1 PATH2 PATH3 -type f -printf '%T@ %p\n'), затем сортирует список по дате (sort -nr), затем пропускает первые четыре записи (tail -n+5). Наконец, информация о времени отбрасывается (cut -f 2- -d " "), и результат впоследствии передается в xargs, который генерирует и выполняет соответствующую команду rm.

0

Самый простой способ:

for d in dir1 dir2 dir3; do
  rm -vf `ls -1t $d | head -n-4` 
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .