Bash скрипт для удаления файлов старше x дней с подкаталогами

37

Я пытаюсь удалить тонну файлов старше x дней.

Теперь у меня есть скрипт для этого

find /path/to/files* -mtime +10 -exec rm {} \; 

Но это также удалит подкаталоги. Существует множество папок, но я хотел бы сохранить их и удалить файлы старше 10 дней из указанных папок.

Есть ли способ сделать это?

ДжойИан Йи-Эрнандес
источник

Ответы:

50

type опция для фильтрации результатов

findпринимает typeопцию для выбора, например, только файлов.

find /path/to/files -type f -mtime +10 -delete

Оставьте, -deleteчтобы показать, что он будет удалять, и как только вы это проверите, продолжайте и выполните полную команду.

Это будет работать только на файлы, а не каталоги. Используйте -type dдля обратного, только список каталогов, которые соответствуют вашим аргументам.


Дополнительные опции

Возможно, вы захотите прочитать man find, поскольку в будущем вам может понадобиться еще несколько опций. Например, -maxdepthпозволит вам ограничить только найденные элементы определенной глубиной, например -maxdepth 0, не будет возвращаться в подкаталоги.

Некоторые замечания

  • Интересно, как команда удалила папку, так как вы не можете удалить папку rmтолько с. Вам нужно rm -rдля этого.

  • Также /path/to/files*сбивает с толку. Вы имели в виду /path/to/files/или ожидаете, что подстановочный знак расширится до нескольких имен файлов и папок?

  • Поместите {}в одинарные кавычки, т. Е. '{}'Чтобы избежать замены интерпретируемого оболочкой имени файла / каталога, как мы защищаем точку с запятой обратной косой чертой.

slhck
источник
Ну, в каталоге / path / to / files / есть много папок. На самом деле я бы хотел запустить mtime +10 -exec rm для каждой из этих папок, но оставить эти папки сами, в основном я хотел бы добиться того, чтобы удалить все файлы старше 10 дней и сохраните все папки. Я новичок, извините насчет этого новизны :)
JoyIan Йи-Эрнандес
Ну что ж, поехали :) Просто сделайте find /path/to/files* -type f -mtime +10и посмотрите, что из этого получится.
Slhck
Да, когда сомневаешься, не делай этого -exec, просто посмотри, что он найдет первым.
Роб
2
@ JoyIanYee-Hernandez Вы также можете использовать -deleteаргумент для find, который удаляет все файлы и папки, последние, только если они пусты. Это предполагает -depthпоиск в глубину.
Даниэль Бек
1
@Kreker Затем вам нужно добавить, -mindepth 1чтобы исключить родительский каталог.
Slhck
5

Как и в предыдущих ответах (+1 для обоих), хитрость заключается в использовании -type fпредиката.

Обратите внимание, что вместо -exec rm '{}'вас также можно использовать -deleteпредикат. Но не делай этого. С помощью -exec rm '{}'вы можете (и должны) сначала сделать, -exec echo rm '{}'чтобы убедиться, что это действительно то, что вы хотите. После этого повторите команду без echo.

Использование -deleteвыполняется быстрее (без дополнительных затрат fork()и execve()для каждого файла), но это рискованно, поскольку -deleteработает также как условие, поэтому:

# delete *.tmp files
find . -type f -name '*.tmp' -delete

но если вы ТОЛЬКО меняете аргументы:

# delete ALL files
find . -type f -name '*.tmp' -delete

Если вы когда - нибудь понадобится findи rmработать быстрее тонн файлов, проверьте find ... | xargs ... rmидиомы UNIX.

Михал Шрайер
источник
4
Я думаю, что ваши последние два примера точно такие же, возможно, захотите исправить это!
slhck
1

Вы можете легко сделать это с помощью команды find

$ find -type f

Что ограничивает результаты для файла типа

Бернхард
источник
1

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

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

tmpreaper -t 5d ~/Downloads


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

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

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

user52573
источник
0

Для ускорения команды используйте '+'вместо\;

find /path/to/files* -type f -mtime +10 -exec rm '{}' '+'

Это будет выполняться rmтолько один раз в конце, а не каждый раз, когда файл будет найден.
( rmможет запускаться несколько раз, если у вас действительно много файлов из-за ограничения длины командной строки, но это все равно почти так же быстро, как и при использовании -delete)

olibre
источник
0

рм -ф find /path/to/files -type file -mtime -5

Это удалит файлы, которые были изменены в течение 5 дней

рм -ф find /path/to/files -type file -mtime +5

Это удалит файлы, которые были изменены ранее 5 дней

Используйте `перед поиском и в конце после 5.

Нихил Шинде
источник