Como excluir o diretório superior que contém todos os arquivos dentro modificados pelo menos n dias antes de hoje?

0

Considere a seguinte estrutura de pastas

dir
    sandbox1
        mywebsite file 
        ...
    sandbox2
        mywebsite file
        ...

Eu tenho milhares desses diretórios do sandbox criados pelos meus colegas.

Como estamos ficando sem inode, decidimos excluir o diretório do sandbox que tem conteúdo não modificado por 20 dias.

por exemplo,

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)
        ...

Nesse caso, o sandbox1 será excluído, pois não foi modificado por 20 dias e seu conteúdo não foi modificado por 20 dias

O Sandbox2 não será excluído, pois possui um conteúdo que foi modificado há 19 dias

Eu sei

find /dir/ -maxdepth 1 -mtime +n 

encontra todos os diretórios modificados pelo menos n dias, mas o conteúdo dentro de cada diretório não é refletido.

Existe uma maneira de encontrar todos os diretórios de modo que o diretório e seu conteúdo não tenham sido modificados por n dias?

Qualquer ajuda seria apreciada.

    
por user445670 03.11.2016 / 19:43

1 resposta

0

Se os tempos de modificação do arquivo forem críticos para você, será necessário verificar os horários de modificação do arquivo e não o horário de modificação dos diretórios pai. O último só muda quando a estrutura do diretório muda (ou seja, um arquivo foi criado, movido / renomeado ou desvinculado). As alterações no arquivo conteúdo não são refletidas no registro de data e hora do diretório pai.

Portanto, podemos encontrar todos os arquivos recentemente modificados (menos de 20 × 24 h atrás) em uma árvore de diretórios com:

find /some/path -type f -mtime -20

Podemos restringir a saída para mostrar apenas nomes de diretórios exclusivos:

find /some/path -type f -mtime -20 -printf '%h\n' | uniq

Localizar todos os diretórios sem arquivos modificados recentemente

Se precisarmos encontrar todos os diretórios sem entradas profundas modificadas recentemente, será mais complicado, já que precisamos calcular o conjunto invertido, que é a diferença do conjunto de todos os diretórios dentro da árvore e do conjunto computado anteriormente. Podemos usar facilmente a ação -printf para particionar a saída de find para, pelo menos, listar todos os dados de que precisamos:

find /some/path -mindepth 1 \( -type d -printf '+%p\n' \) -o \( -type f -mtime -20 -printf '-%h\n' \) | uniq
Infelizmente, as operações definidas não são algo que pode ser feito facilmente em um shell script, então eu escrevi um programa Python que opera na saída do comando find anterior:

#!/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')

Supondo que o programa anterior está em ~/tree-difference.py , podemos usá-lo assim:

find /some/path -mindepth 1 -depth \( -type d -printf '+%p\n' \) -o \( -type f -mtime -20 -printf '-%h\n' \) | python3 ~/tree-difference.py

Verifique o resultado

Você provavelmente quer verificar se você (ou eu) não cometeu um erro que exclui acidentalmente os arquivos modificados recentemente. Felizmente, podemos usar uma variação do comando original find para inspecionar todos os diretórios retornados por tree-difference.py . Ele lista todos os arquivos modificados recentemente, então uma saída vazia significa que tudo correu conforme o planejado. Isso pode demorar um pouco se tivermos muitos arquivos.

O seguinte comando obtém sua entrada da saída de tree-difference.py (com um pipe ou arquivo intermediário):

xargs -rd '\n' -I{} -- find {} -mindepth 1 -type f -mtime -20

Excluir os diretórios encontrados

Este é simples. A entrada é a saída de tree-difference.py .

xargs -rd '\n' -- rm -rf --

Se rm reclamar de diretórios não existentes, porque você esqueceu a opção -depth no comando find que serve como entrada de tree-difference.py .

    
por David Foerster 05.11.2016 / 12:42