Como excluir arquivos com mais de X horas

191

Estou escrevendo um script bash que precisa excluir arquivos antigos.

Atualmente, é implementado usando:

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

Isso excluirá os arquivos com mais de 1 dia.

No entanto, e se eu precisar de uma resolução mais refinada nesse dia, digamos, com 6 horas? Existe uma boa maneira limpa de fazer isso, como se estivesse usando find e -mtime?

Tom Feiner
fonte

Respostas:

303

Você findtem a -mminopção? Isso permite testar o número de minutos desde a última modificação:

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

Ou talvez veja usando tmpwatchpara fazer o mesmo trabalho. phjr também recomendado tmpreapernos comentários.

Paul Dixon
fonte
2
Usar --mmin + X retorna todos os arquivos com a minha localização. A culpa foi minha por não ter verificado isso primeiro, mas esse comando acabou de excluir a maior parte do meu diretório pessoal. Para mim, --mmin -X é o argumento correto.
brandones
tmpreaper é um fork do tmpwatch. É mais seguro e existe como um pacote debian na distribuição. Benefícios sobre encontrar -delete: tmpreaper não irá remover links simbólicos, sockets, FIFOs, ou arquivos especiais
Nadir
Saliente que $ REQUIRED_FILES precisa estar entre aspas (aspas duplas) e você pode usar um padrão como: " .txt" para todos os arquivos .txt ou arquivos começando com um padrão como: "temp- " para excluir todos os arquivos nomeados com temp -
achasinh
@PaulDixon como modificar isso para que $LOCATIONe $REQUIRED_FILESambos possam ter vários valores, como dir1 dir2e *.txt *.tmp?
Enissay
@Enissay $ LOCATION é um único diretório. Para várias extensões que você provavelmente gostaria de usar um padrão com -regex - ver stackoverflow.com/questions/5249779/...
Paul Dixon
9

Você pode fazer esse truque: crie um arquivo 1 hora atrás e use o -newer fileargumento

(Ou use touch -tpara criar esse arquivo).

xtofl
fonte
1
não há opção -older (pelo menos no meu comando find), e é isso que seria necessário. -novo não ajuda.
Iconoclast
você pode dar um comando de toque que geraria um arquivo com uma hora de duração que funcionará em máquinas que não podem usar -mmin? (Se você estiver em Linux, -mmin está disponível, se não, em seguida, data e outros comandos também são fracos em comparação.)
iconoclasta
2
@iconoclast touch -t $(date -d '-1 hour' +%Y%m%d%H%M.00) testCria um arquivo testcom sempre 1 hora de idade.
rovr138
4

Aqui está a abordagem que funcionou para mim (e não a vejo sendo usada acima)

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

excluir todos os arquivos com mais de 59 minutos e deixar as pastas intactas.

Axel Ronsin
fonte
Melhor citar entre aspas simples '*.*'ou o shell o expandirá para nomes de arquivos reais, em vez de mantê-lo como um curinga para findresolver. Isso interrompe finda operação recursiva em subdiretórios.
MestreLion 20/02/19
Também tenha em mente que -name '*.*'não vai apagar arquivos que não têm extensão, como README, Makefile, etc.
MestreLion
1

Para 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.
Rajeev Rumale
fonte
0

-mmin é por minutos.

Tente olhar para a página do manual.

man find

para mais tipos.

GavinCattell
fonte
0

Se você não possui "-mmin" em sua versão de "find", "-mtime -0.041667" fica muito próximo de "dentro da última hora"; portanto, no seu caso, use:

-mtime +(X * 0.041667)

então, se X significa 6 horas, então:

find . -mtime +0.25 -ls

funciona porque 24 horas * 0,25 = 6 horas

Malcolm Boekhoff
fonte
Estava esperançoso porque este UNIX antigo não possui -mmin, mas, infelizmente, isso não ajuda em nada, pois esse UNIX antigo também não gosta de valores fracionários para mtime: find: o argumento para -mtime deve ser um número inteiro no intervalo -2147483647 a 2147483647
kbulgrien 16/04
0

Aqui está o que se pode fazer pelo caminho que a @iconoclast estava pensando em seu comentário sobre outra resposta.

use crontab para usuário ou an /etc/crontabpara criar arquivo /tmp/hour:

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

e use isso para executar seu comando:

find /tmp/ -daystart -maxdepth 1 -not -newer /tmp/hour -type f -name "for_one_hour_files*" -exec do_something {} \;
satyr0909
fonte
*/1por hora é redundante em seu crontab. É o mesmo que colocar * no campo da hora.
Colm.anseo
0

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

Eragonz91
fonte
0

Se a pessoa findnão tem -mmine se também está presa a uma findque aceita apenas valores inteiros -mtime, então nem tudo está perdido se considerarmos que "mais antigo que" é semelhante a "não mais novo que".

Se formos capazes de criar um arquivo que tenha um tempo mínimo de nosso tempo limite, podemos pedir findpara localizar os arquivos que "não são mais novos que" nosso arquivo de referência.

Para criar um arquivo que tem o carimbo de hora correta é um pouco envolvido, porque um sistema que não tenha uma adequada findprovavelmente também tem uma menos-que-capazes datede comando que poderia fazer coisas como: date +%Y%m%d%H%M%S -d "6 hours ago".

Felizmente, outras ferramentas antigas que podem gerenciar isso, ainda que de uma maneira mais difícil.

Considere que seis horas são 21600 segundos. Queremos encontrar o horário de seis horas atrás em um formato útil:

$ 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

A declaração perl produziu uma data útil, mas precisa ser melhor utilizada:

$ 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

Agora, a solução para esse UNIX antigo é algo parecido com:

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

Também pode ser uma boa ideia limpar nosso arquivo de referência ...

$ rm -f ref_file
Kbulgrien
fonte