Script de shell para excluir diretórios com mais de n dias

165

Eu tenho diretórios nomeados como:

2012-12-12
2012-10-12
2012-08-08

Como excluir os diretórios com mais de 10 dias com um script de shell bash?

bobsr
fonte
1
Eles descobriram alguma relação com o tempo real de criação / modificação? Porque findpoderia fazê-lo sem olhar para o nome, então ...
Wrikken
eles devem ter tempo de criação / modificação sobre eles também
bobsr
4
O que você quer dizer com "mais velho que"? Você está se referindo à hora em que o diretório foi criado, a hora em que seu conteúdo foi alterado pela última vez ou algo mais? Tenha cuidado com algumas das respostas abaixo; ctimeé o tempo de mudança do inode. Para um diretório, ele muda quando os arquivos são adicionados ou removidos do diretório.
ajk

Respostas:

390

Isso fará isso recursivamente para você:

find /path/to/base/dir/* -type d -ctime +10 -exec rm -rf {} \;

Explicação:

  • find: o comando unix para encontrar arquivos / diretórios / links etc.
  • /path/to/base/dir: o diretório para iniciar sua pesquisa.
  • -type d: encontre apenas diretórios
  • -ctime +10: considere apenas aqueles com tempo de modificação superior a 10 dias
  • -exec ... \;: para cada resultado encontrado, execute o seguinte comando em ...
  • rm -rf {}: forçar recursivamente a remover o diretório; a {}parte é onde o resultado da busca é substituído pela parte anterior.

Como alternativa, use:

find /path/to/base/dir/* -type d -ctime +10 | xargs rm -rf

O que é um pouco mais eficiente, porque equivale a:

rm -rf dir1 dir2 dir3 ...

em oposição a:

rm -rf dir1; rm -rf dir2; rm -rf dir3; ...

como no -execmétodo


Nas versões modernas de find, você pode substituir o ;por +e ele fará o equivalente da xargschamada para você, transmitindo quantos arquivos caberem em cada chamada do sistema exec:

find . -type d -ctime +10 -exec rm -rf {} +
sampson-chen
fonte
12
-mtimefoi melhor para mim, pois verifica as alterações de conteúdo em vez das alterações de permissão, caso contrário, isso era perfeito.
quickshiftin
7
Eu acho que isso também irá excluir o próprio diretório base
Ou Gal
3
@OrGal, você está absolutamente correto. A fim de evitar isso, basta usar: find /path/to/base/dir/*.
Zloynemec 5/07
11
você pode usar -maxdepth 1 para ignorar o conteúdo dos diretórios
Sam
7
A abordagem mais eficiente pode sair pela culatra se você tiver muitas pastas para excluir: stackoverflow.com/questions/11289551/… . Pelo mesmo motivo, para evitar a exclusão da pasta base, é melhor usar -mindepth 1(em vez de /path/to/folder/*).
Oade Schneider
41

Se você deseja excluir todos os subdiretórios em /path/to/base, por exemplo

/path/to/base/dir1
/path/to/base/dir2
/path/to/base/dir3

mas você não deseja excluir a raiz /path/to/base, adicione -mindepth 1e -maxdepth 1opções, que acessarão apenas os subdiretórios em/path/to/base

-mindepth 1 exclui a raiz /path/to/base das correspondências.

-maxdepth 1vai SOMENTE corresponder subdiretórios imediatamente sob /path/to/basetais como /path/to/base/dir1, /path/to/base/dir2e /path/to/base/dir3mas não vai lista subdiretórios destes de forma recursiva. Portanto, esses subdiretórios de exemplo não serão listados:

/path/to/base/dir1/dir1
/path/to/base/dir2/dir1
/path/to/base/dir3/dir1

e assim por diante.

Portanto, para excluir todos os subdiretórios nos /path/to/basequais há mais de 10 dias;

find /path/to/base -mindepth 1 -maxdepth 1 -type d -ctime +10 | xargs rm -rf
pmgarvey
fonte
19

findsuporta -deleteoperação, então:

find /base/dir/* -ctime +10 -delete;

Eu acho que há um problema de que os arquivos também precisam ter mais de 10 dias. Ainda não tentei, alguém pode confirmar nos comentários.

A solução mais votada aqui está ausente -maxdepth 0e, portanto, ela será chamada rm -rfpara todos os subdiretórios, após a exclusão. Isso não faz sentido, então sugiro:

find /base/dir/* -maxdepth 0  -type d -ctime +10 -exec rm -rf {} \;

A -deletesolução acima não usa -maxdepth 0porque findreclamaria que o dir não está vazio. Em vez disso, implica -depthe exclui de baixo para cima.

Ondra Žižka
fonte
Posso confirmar -deletetrabalhos, mas, como você disse, só pode usá-lo para excluir diretórios vazios, assim como rmdir.
precisa saber é
3

Eu estava lutando para acertar isso usando os scripts fornecidos acima e alguns outros scripts, especialmente quando os nomes de arquivos e pastas tinham nova linha ou espaços.

Finalmente tropeçamos no tmpreaper e ele tem funcionado muito bem para nós até agora.

tmpreaper -t 5d ~/Downloads


tmpreaper  --protect '*.c' -t 5h ~/my_prg

Link da fonte original

Possui recursos como teste, que verifica os diretórios recursivamente e os lista. Capacidade de excluir links simbólicos, arquivos ou diretórios e também o modo de proteção para um determinado padrão ao excluir

user_v
fonte
2

OU

rm -rf `find /path/to/base/dir/* -type d -mtime +10`

Versão atualizada e mais rápida:

find /path/to/base/dir/* -mtime +10 -print0 | xargs -0 rm -f
Impressionante
fonte
2
Este poderia facilmente exceder o comprimento máximo da linha de comando. Veja xargs --show-limits.
Michael Krupp
2
Também não funcionará se houver nomes de arquivos contendo espaços ou outros caracteres especiais do shell.
Martin Tournoij
@Carpetsmoker O -print0/ não -0cuida dos caracteres especiais do shell, ou não?
Mpr
Você está certo que a xargsversão será @mpen, mas a primeira linha não.
Martin Tournoij