Сценарий оболочки для удаления каталогов старше n дней

165

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

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

Как бы я удалил каталоги старше 10 дней скриптом оболочки bash?

bobsr
источник
1
Чтобы они имели какое-либо отношение к их фактическому времени создания / модификации? Потому что findмог сделать это, не глядя на имя тогда ...
Wrikken
у них также должно быть время создания / модификации
bobsr 13.12.12
4
Что вы подразумеваете под "старше, чем"? Вы имеете в виду время создания каталога, время последнего изменения его содержимого или что-то еще? Будьте осторожны с некоторыми ответами ниже; ctimeвремя смены инода Для каталога это изменяется, когда файлы добавляются или удаляются из каталога.
ajk

Ответы:

391

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

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методе.


В современных версиях findвы можете заменить на ;with, +и он сделает xargsдля вас эквивалент вызова, передав столько файлов, сколько поместится в каждом системном вызове exec:

find . -type d -ctime +10 -exec rm -rf {} +
Сэмпсон-чен
источник
13
-mtimeбыло лучше для меня, так как он проверяет изменения содержимого, а не изменения разрешений, в противном случае это было идеально.
quickshiftin
7
Я думаю, что это также удалит сам базовый каталог
Или Гал
3
@ Orgal ты абсолютно прав. Для того , чтобы предотвратить это, просто использовать: find /path/to/base/dir/*.
zloynemec
11
Вы можете использовать -maxdepth 1, чтобы игнорировать содержимое каталогов
Сэм
7
Более эффективный подход может иметь неприятные последствия, если у вас слишком много папок для удаления: stackoverflow.com/questions/11289551/… . По той же причине, чтобы избежать удаления базовой папки, лучше использовать -mindepth 1(а не /path/to/folder/*).
Охад Шнайдер
41

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

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

но вы не хотите удалять корень /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
pmgarvey
источник
20

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Выше раствор не используется , -maxdepth 0потому findчто жалуются каталог не пустой. Вместо этого он подразумевает -depthи удаляет снизу вверх.

Ондра Жижка
источник
Я могу подтвердить -deleteработу, но, как вы сказали, вы можете использовать ее только для удаления пустых каталогов, как rmdir.
CTodea
3

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

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

tmpreaper -t 5d ~/Downloads


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

Исходная ссылка

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

user_v
источник
2

ИЛИ

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

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

find /path/to/base/dir/* -mtime +10 -print0 | xargs -0 rm -f
Потрясающие
источник
2
Это может легко превысить максимальную длину командной строки. См xargs --show-limits.
Майкл Крупп
2
Также не будет работать, если есть имена файлов, содержащие пробелы или другие специальные символы оболочки.
Мартин Турной
Не @Carpetsmoker ли не -print0/ -0заботиться о специальных символах оболочки, или нет?
mpen
Вы правы, что xargsверсия будет @mpen, но первая строка - нет.
Мартин Турной