Подтвердить что ты не робот

Bash команда удалить все, кроме последних 5 каталогов

Возможный дубликат:
Удалить все, кроме последних X файлов в bash

У меня есть script для создания инкрементных резервных копий ежедневно, и мне нужно удалить все резервные копии, но последние 5.

Например, у меня есть следующие папки:

drwxr-xr-x  4 root root 4096 Oct 29 01:10 2010-10-29
drwxr-xr-x  4 root root 4096 Oct 30 01:10 2010-10-30
drwxr-xr-x  4 root root 4096 Oct 31 01:10 2010-10-31
drwxr-xr-x  4 root root 4096 Nov  1 01:10 2010-11-01
drwxr-xr-x  4 root root 4096 Nov  2 01:10 2010-11-02
drwxr-xr-x  4 root root 4096 Nov  3 01:10 2010-11-03
drwxr-xr-x  4 root root 4096 Nov  4 01:10 2010-11-04
drwxr-xr-x  4 root root 4096 Nov  5 01:10 2010-11-05
drwxr-xr-x  4 root root 4096 Nov  6 01:10 2010-11-06
drwxr-xr-x  4 root root 4096 Nov  7 01:10 2010-11-07
drwxr-xr-x  4 root root 4096 Nov  8 01:10 2010-11-08

И мне нужно поддерживать только последние 5 каталогов и удалять остальные. После выполнения команды мне нужно иметь только это:

drwxr-xr-x  4 root root 4096 Nov  4 01:10 2010-11-04
drwxr-xr-x  4 root root 4096 Nov  5 01:10 2010-11-05
drwxr-xr-x  4 root root 4096 Nov  6 01:10 2010-11-06
drwxr-xr-x  4 root root 4096 Nov  7 01:10 2010-11-07
drwxr-xr-x  4 root root 4096 Nov  8 01:10 2010-11-08

Мне не нужно удалять предыдущие 5 дней, мне нужно удалить все, кроме 5 последних каталогов:)

Теперь я использую:

find /backup/increment -maxdepth 1 -type d -mtime +5 -exec rm -rf {} \;

Но мне нужно совершенствоваться не вовремя:)

EDIT:. Это пример для сервера, который делает резервные копии в течение всего дня, но мне нужен script, который удаляет все папки, предшествующие последним 5, потому что мой компьютер делает резервные копии в 00:10 на ночь, но не все ночи резервное копирование сделано, потому что мой компьютер не работает все дни, и мне нужно иметь всегда последние 5 резервных копий:)

4b9b3361

Ответ 1

используйте команду tail для печати строк, начинающихся с n-й строки (Option -n +N):

rm `ls -t | tail -n +6`

ls -t выводит текущий каталог, отсортированный по времени. tail -n +6 берет al строки, начиная с 6-й строки. Цитирование с backticks подает результат трубы в команду rm.

OLD SOLUTION, не правильно...

используйте команду head, которая печатает первые n строк некоторого вывода:

rm `ls -t1 | head -n 5`

ls -t выводит текущий каталог, отсортированный по времени. head -n 5 берет первые пять записей предыдущего вывода. Цитирование с backticks подает результат трубы в команду rm.

Пожалуйста, попробуйте сначала, прежде чем подать заявку на живые данные:)...

Ответ 2

Первое, что пришло мне в голову. Это не изящно:

a=0;
for i in `ls -t`;
do
    a=`expr $a + 1`;
    if [ $a  -gt 5 ]; then
          echo "removing $i";
          rm -rf $i
    fi;
done

Ответ 3

создать два фиктивных файла с началом и датой окончания

touch -t 1010290000 before
touch -t 2011042359 after

найти все файлы между двумя фиктивными файлами и "rm -rf" результат

find . -newer before \! -newer after -exec rm -rf {} \;

Ответ 4

ls -tr | perl -ne '{@files = < > ; print @files [0.. $# files-5]} '| xargs -n1 echo rm -rf

Вы должны удалить эхо перед rm -rf, чтобы заставить его работать.

Ответ 5

Трюк будет опцией -t для ls, которая сортирует по времени модификации от самого нового до самого старого.

На самом деле наивное решение, использующее временный файл, может идти следующим образом:

ls -t > /tmp/file_list
num_files_to_keep=5
# wc -l gets the line count of a file
# first word of wc output is the actual line count, and that all we need, so
# delete everything after the space.
num_files=`wc -l /tmp/file_list | sed "s/ .*//"`
#if appropriate you should add a check for num_files < num_files_to_keep
num_files_to_delete=$(( $num_files - $num_files_to_keep ))
rm `tail -n $num_files_to_delete /tmp/file_list`