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
.