Рассмотрите следующую структуру папок
dir
sandbox1
mywebsite file
...
sandbox2
mywebsite file
...
У меня есть тысячи из них, играют в песочнице каталог, созданный моими коллегами.
Так как у нас заканчивается inode, мы решаем удалить каталог песочницы, который имеет содержание, не измененное в течение 20 дней.
например.
dir
sandbox1 (modified 23 days ago)
mywebsite file (modified 22 days ago)
... (modified 24 days ago)
sandbox2 (modified 23 days ago)
mywebsite file (modified 19 days ago)
...
В этом случае sandbox1 будет удален, так как он не изменялся в течение 20 дней, и его содержание не изменялось в течение 20 дней
Sandbox2 не будет удален, так как он имеет содержание, которое изменяется 19 дней назад
Я знаю
find /dir/ -maxdepth 1 -mtime +n
находит весь каталог измененным, по крайней мере, n дни, но содержание в каждом каталоге не отражается.
Существует ли способ найти весь каталог таким образом, что каталог и его содержание не были изменены в течение n дней?
Любая справка ценилась бы.
Если время изменения файла очень важно для Вас затем, необходимо посмотреть на время изменения файла а не время изменения их родительских каталогов. Последние только изменяются, когда структура изменений каталога (т.е. файл был создан, переместилась/переименовала или удалила связь). Изменения для регистрации содержания не отражаются в метке времени родительского каталога.
Поэтому мы можем найти весь недавно измененный (меньше, чем 20×24 несколько ч назад) файлы в дереве каталогов с:
find /some/path -type f -mtime -20
Мы можем ограничить вывод для показа только уникальных имен каталогов:
find /some/path -type f -mtime -20 -printf '%h\n' | uniq
Если мы должны найти все каталоги без недавно измененных глубоких записей, это становится более хитрым, так как мы должны вычислить инвертированный набор, который является разностью множеств набора всех каталогов в дереве и ранее вычисленного набора. Мы можем легко использовать -printf
действие для разделения вывода find
чтобы, по крайней мере, перечислить все данные, нам нужно:
find /some/path -mindepth 1 \( -type d -printf '+%p\n' \) -o \( -type f -mtime -20 -printf '-%h\n' \) | uniq
К сожалению, операции присвоения не что-то, что может быть легко сделано в сценарии оболочки, таким образом, я записал программу Python, которая воздействует на вывод предыдущего find
команда:
#!/usr/bin/env python3
import sys, os.path
from itertools import filterfalse
def parent_dir_generator( path ):
while path:
yield path
path = os.path.dirname(path)
all_dirs = list()
keep_dirs = set()
keep_dir_parents = set()
for line in filter(bool, map(lambda s: s.rstrip('\n'), sys.stdin)):
path = line[1:]
if path.startswith('./'):
path = path[2:]
if line.startswith('+'):
all_dirs.append(path)
elif line.startswith('-'):
keep_dirs.add(path)
keep_dir_parents.update(parent_dir_generator(path))
diff_dirs = filterfalse(
lambda path: any(map(keep_dirs.__contains__, parent_dir_generator(path))),
filterfalse(keep_dir_parents.__contains__, all_dirs))
print(*diff_dirs, sep='\n')
Принятие предыдущей программы в ~/tree-difference.py
мы можем использовать его как это:
find /some/path -mindepth 1 -depth \( -type d -printf '+%p\n' \) -o \( -type f -mtime -20 -printf '-%h\n' \) | python3 ~/tree-difference.py
Вы, вероятно, хотите проверить, что Вы (или I) не сделали ошибку, которая случайно удаляет недавно измененные файлы. К счастью, мы можем использовать изменение оригинала find
команда для осмотра всех каталогов, возвращенных tree-difference.py
. Это перечисляет все недавно измененные файлы в них, таким образом, пустой вывод означает, что все пошло согласно плану. Это может занять долгое время, если у нас есть много файлов.
Следующая команда берет свой вход от вывода tree-difference.py
(с каналом или промежуточным файлом):
xargs -rd '\n' -I{} -- find {} -mindepth 1 -type f -mtime -20
Этот прост. Вход является выводом tree-difference.py
.
xargs -rd '\n' -- rm -rf --
Если rm
жалуется на несуществующие каталоги поэтому, Вы забыли -depth
опция в find
команда, служащая входом tree-difference.py
.