Shell script для удаления каталогов старше n дней

У меня есть каталоги, названные так:

2012-12-12
2012-10-12
2012-08-08

Как удалить каталоги старше 10 дней с помощью bash оболочки script?

Ответ 1

Это будет рекурсивно для вас:

find /path/to/base/dir/* -type d -ctime +10 -exec rm -rf {} \;

Объяснение:

  • find: команда unix для поиска файлов/каталогов/ссылок и т.д.
  • /path/to/base/dir: каталог для начала поиска.
  • -type d: найти только каталоги
  • -ctime +10: учитывайте только те, у кого время модификации старше 10 дней.
  • -exec ... \;: для каждого найденного результата выполните следующую команду в ...
  • rm -rf {}: рекурсивно принудительно удалите каталог; часть {} - это то, где результат поиска заменяется на предыдущую часть.

В качестве альтернативы используйте:

find /path/to/base/dir/* -type d -ctime +10 | xargs rm -rf

Это немного более эффективно, потому что оно равно:

rm -rf dir1 dir2 dir3 ...

в отличие от:

rm -rf dir1; rm -rf dir2; rm -rf dir3; ...

как в методе -exec.

Примечание. Также см. комментарий @MarkReed ниже относительно предпочтительного использования с современной версией find.

Ответ 2

Если вы хотите удалить все подкаталоги в /path/to/base, например

/path/to/base/dir1
/path/to/base/dir2
/path/to/base/dir3

но вы не хотите удалять root /path/to/base, вам нужно добавить опции -mindepth 1 и -maxdepth 1, которые будут иметь доступ только к подкаталогам под /path/to/base

-mindepth 1 исключает корень /path/to/base из совпадений.

-maxdepth 1 будет ТОЛЬКО сопоставлять подкаталоги непосредственно в /path/to/base, такие как /path/to/base/dir1, /path/to/base/dir2 и /path/to/base/dir3, но он не будет перечислять их подкаталоги рекурсивным образом. Поэтому эти подкаталоги примера не будут перечислены:

/path/to/base/dir1/dir1
/path/to/base/dir2/dir1
/path/to/base/dir3/dir1

и т.д.

Итак, чтобы удалить все подкаталоги в /path/to/base, которые старше 10 дней,

find /path/to/base -mindepth 1 -maxdepth 1 -type d -ctime +10 | xargs rm -rf

Ответ 3

find поддерживает операцию -delete, поэтому:

find /base/dir/* -ctime +10 -delete;

Я думаю, что есть уловка, что файлы должны быть на 10 + дней старше. Не пробовал, кто-то может подтвердить в комментариях.

Самое проголосовавшее решение здесь отсутствует -maxdepth 0, поэтому он будет вызывать rm -rf для каждого подкаталога после его удаления. Это не имеет смысла, поэтому я предлагаю:

find /base/dir/* -maxdepth 0  -type d -ctime +10 -exec rm -rf {} \;

-delete не использует это, потому что find будет жаловаться, что каталог не пуст. Вместо этого он подразумевает -depth и удаляет снизу вверх.

Ответ 4

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

Наконец-то наткнулся на tmpreaper, и до сих пор он работал очень хорошо.

tmpreaper -t 5d ~/Downloads


tmpreaper  --protect '*.c' -t 5h ~/my_prg

Исходный источник ссылка

Имеет такие функции, как test, который рекурсивно проверяет каталоги и перечисляет их. Возможность удаления символических ссылок, файлов или каталогов, а также режим защиты для определенного шаблона при удалении

Ответ 5

ИЛИ

rm -rf `find /path/to/base/dir/* -type d -mtime +10`

Обновлена, более быстрая версия:

find /path/to/base/dir/* -mtime +10 -print0 | xargs -0 rm -f