Как удалить главный каталог, которые содержат все файлы, внутри измененные, по крайней мере, n за дни до этого сегодня?

Рассмотрите следующую структуру папок

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 дней?

Любая справка ценилась бы.

0
задан 4 November 2016 в 00:52

1 ответ

Если время изменения файла очень важно для Вас затем, необходимо посмотреть на время изменения файла а не время изменения их родительских каталогов. Последние только изменяются, когда структура изменений каталога (т.е. файл был создан, переместилась/переименовала или удалила связь). Изменения для регистрации содержания не отражаются в метке времени родительского каталога.

Поэтому мы можем найти весь недавно измененный (меньше, чем 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.

0
ответ дан 28 September 2019 в 06:24

Другие вопросы по тегам:

Похожие вопросы: