Как удалить файлы старше X часов

191

Я пишу сценарий bash, который должен удалить старые файлы.

В настоящее время это реализовано с использованием:

find $LOCATION -name $REQUIRED_FILES -type f -mtime +1 -delete

Это удалит файлы старше 1 дня.

Однако, что если мне понадобится более точное разрешение за 1 день, скажем, около 6 часов? Есть ли хороший чистый способ сделать это, например, использование find и -mtime?

Том Файнер
источник

Ответы:

303

У вас findесть -mminвозможность? Это может позволить вам проверить количество минут с момента последней модификации:

find $LOCATION -name $REQUIRED_FILES -type f -mmin +360 -delete

Или, может быть, посмотрите на использование, tmpwatchчтобы сделать ту же работу. phjr также рекомендуется tmpreaperв комментариях.

Пол Диксон
источник
2
Использование --mmin + X возвращает все файлы с моей находкой. Я виноват в том, что не проверил это первым, но эта команда просто удалила большую часть моего домашнего каталога. Для меня --mmin -X - правильный аргумент.
Brandones
tmpreaper - это форк tmpwatch. Это безопаснее и существует как дистрибутив Debian. Преимущества по сравнению с find -delete: tmpreaper не будет удалять символические ссылки, сокеты, fifos или специальные файлы
Nadir
Укажите, что $ REQUIRED_FILES должны быть в кавычках (двойные кавычки), и вы можете использовать шаблон, например: « .txt», для всех файлов .txt или файлов, начинающихся с шаблона, например: «temp- », чтобы удалить все файлы, названные с помощью temp. -
Ахасин
@PaulDixon, как изменить это так, чтобы $LOCATIONи $REQUIRED_FILESоба могли иметь несколько значений, таких как dir1 dir2и *.txt *.tmp?
Enissay
@Enissay $ LOCATION - это один каталог. Для нескольких расширений вы, вероятно, захотите использовать шаблон с -regex - см. Stackoverflow.com/questions/5249779/…
Пол Диксон
9

Вы могли бы сделать этот трюк: создать файл 1 час назад и использовать -newer fileаргумент.

(Или используйте touch -tдля создания такого файла).

xtofl
источник
1
здесь нет ключа -older (по крайней мере, в моей команде find), и это то, что нужно. -новое не помогает.
иконоборчество
Можете ли вы дать команду touch, которая сгенерирует файл 1 часа, который будет работать на машинах, которые не могут использовать -mmin? (Если вы работаете в Linux, -mmin доступен, если нет, то дата и другие команды также неэффективны в сравнении.)
iconoclast
2
@iconoclast touch -t $(date -d '-1 hour' +%Y%m%d%H%M.00) testСоздает файл, testкоторому всегда 1 час.
rovr138
4

Вот подход, который работал для меня (и я не вижу, чтобы он использовался выше)

$ find /path/to/the/folder -name *.* -mmin +59 -delete > /dev/null

удалив все файлы старше 59 минут, оставив папки нетронутыми.

Аксель Ронсин
источник
Лучше использовать одинарные кавычки, '*.*'или оболочка расширит его до фактических имен файлов, вместо того, чтобы использовать его в качестве символа подстановки для findразрешения. Это прерывает findрекурсивную операцию над подкаталогами.
MestreLion
Кроме того, имейте в виду , что -name '*.*'будет не удалять файлы , которые не имеют расширения, такие как README, Makefileи т.д.
MestreLion
1

Для SunOS 5.10

 Example 6 Selecting a File Using 24-hour Mode


 The descriptions of -atime, -ctime, and -mtime use the  ter-
 minology n ``24-hour periods''. For example, a file accessed
 at 23:59 is selected by:


   example% find . -atime -1 -print




 at 00:01 the next day (less than 24 hours  later,  not  more
 than one day ago). The midnight boundary between days has no
 effect on the 24-hour calculation.
Раджив Румале
источник
0

-мимин минут.

Попробуйте посмотреть на странице справочника.

man find

для большего количества типов.

GavinCattell
источник
0

Если у вас нет «-mmin» в вашей версии «find», то «-mtime -0.041667» довольно близко подходит к «в течение последнего часа», поэтому в вашем случае используйте:

-mtime +(X * 0.041667)

Итак, если X означает 6 часов, то:

find . -mtime +0.25 -ls

работает потому что 24 часа * 0,25 = 6 часов

Малкольм Бекхофф
источник
Мы надеялись, потому что этот старый UNIX не имеет -mmin, но, к сожалению, это не поможет, так как этот старый UNIX также не любит дробные значения для mtime: find: аргумент -mtime должен быть целым числом в диапазоне от -2147483647 до 2147483647
Кбулгриен
0

Вот то, что можно сделать, чтобы идти по пути, который @iconoclast интересовал в своем комментарии к другому ответу.

используйте crontab для пользователя или a /etc/crontabдля создания файла /tmp/hour:

# m h dom mon dow user  command
0 * * * * root /usr/bin/touch /tmp/hour > /dev/null 2>&1

и затем используйте это для запуска вашей команды:

find /tmp/ -daystart -maxdepth 1 -not -newer /tmp/hour -type f -name "for_one_hour_files*" -exec do_something {} \;
satyr0909
источник
*/1ежечасно избыточно в вашем crontab. Это то же самое, что поставить * в поле часа.
colm.anseo
0

find $PATH -name $log_prefix"*"$log_ext -mmin +$num_mins -exec rm -f {} \;

Eragonz91
источник
0

Если у кого-то findего нет -mminи если он застрял с a, findкоторый принимает только целочисленные значения -mtime, то не обязательно все потеряно, если учесть, что «старше чем» похоже на «не новее чем».

Если мы смогли создать файл, который имеет время отключения, мы можем спросить find найти файлы, которые «не новее» нашего эталонного файла.

Создание файла с правильной отметкой времени немного сложнее, потому что в системе, которая не имеет адекватной, findвероятно, также есть dateкоманда с меньшим количеством возможностей, которая может делать такие вещи, как: date +%Y%m%d%H%M%S -d "6 hours ago" .

К счастью, другие старые инструменты, которые могут управлять этим, хотя и более громоздким способом.

Учтите, что шесть часов - это 21600 секунд. Мы хотим найти время, которое шесть часов назад, в формате, который будет полезен:

$ date && perl -e '@d=localtime time()-21600; \
  printf "%4d%02d%02d%02d%02d.%02d\n", $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]'
> Thu Apr 16 04:50:57 CDT 2020
202004152250.57

Оператор perl действительно дал полезную дату, но ее лучше использовать:

$ date && touch -t `perl -e '@d=localtime time()-21600; \
  printf "%4d%02d%02d%02d%02d.%02d\n", \
  $d[5]+1900,$d[4]+1,$d[3],$d[2],$d[1],$d[0]'` ref_file && ls -l ref_file
Thu Apr 16 04:53:54 CDT 2020
-rw-rw-rw-   1 root     sys            0 Apr 15 22:53 ref_file

Теперь решение для этой старой UNIX выглядит примерно так:

$ find . -type f ! -newer ref_file -a ! -name ref_file -exec rm -f "{}" \;

Также может быть хорошей идеей очистить наш справочный файл ...

$ rm -f ref_file
kbulgrien
источник