Скрипт оболонки для видалення каталогів старше n днів


165

У мене є каталоги, названі як:

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

Як я можу видалити каталоги, старші ніж на 10 днів, за допомогою сценарію bash shell?


1
Чи мають вони якесь відношення до фактичного часу їх створення / модифікації? Тому що findміг би це зробити, не дивлячись на ім’я тоді ...
Wrikken

вони також повинні мати час створення / модифікації
bobsr

4
Що ви маєте на увазі під «старшими за»? Ви маєте на увазі час створення каталогу, час останнього зміни його вмісту чи щось інше? Будьте уважні до деяких відповідей нижче; ctime- час зміни inode. Для каталогу він змінюється, коли файли додаються або видаляються з каталогу.
ajk

Відповіді:


390

Це зробить це для вас рекурсивно:

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, ви можете замінити ;з , +і він буде робити еквівалент xargsвиклику для вас, проходячи стільки файлів , скільки поміститься на кожному ехес системного виклику:

find . -type d -ctime +10 -exec rm -rf {} +

13
-mtimeдля мене було краще, оскільки він перевіряє зміни вмісту, а не зміни дозволу, інакше це було ідеально.
скоромовка

7
Я думаю, що це також видалить базовий dir сам
Або Гал

3
@OrGal ви абсолютно праві. Для того , щоб запобігти цьому, просто використовувати: find /path/to/base/dir/*.
zloynemec

11
ви можете використовувати -maxdepth 1, щоб ігнорувати вміст каталогів
Sam

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

19

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

Посилання на оригінальне джерело

Має такі функції, як тест, який рекурсивно перевіряє каталоги та перераховує їх. Можливість видалення посилань, файлів чи каталогів, а також режим захисту певного шаблону під час видалення


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
Також не буде працювати, якщо є імена файлів, що містять пробіли або інші спеціальні символи оболонки.
Martin Tournoij

@Carpetsmoker Чи не -print0/ -0піклується про особливі символи оболонки, чи ні?
1717

Ви маєте рацію, що xargsверсія буде @mpen, але перший рядок не буде.
Мартін Турнойж
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.