Como deletar milhões de arquivos de um diretório

Bom, como todos sabemos, em certas ocasiões, os diretórios ficam cheios de arquivos indesejáveis que lotam nosso HD.

Isso acontece muitas vezes quando fazemos logs de tudo, usamos arquivos temporários para processamento, ou mesmo, há uma falha em algum sistema que gera lixo nos HDs.

Normalmente, nestes casos, um simples comando “ls” trava por minutos até aparecer a resposta de que a lista é muito longa ou falta memória.

Para isso, temos técnicas de deleção destes arquivos, que são simples e eficazes.

Vamos à elas:

Uma forma para quando ainda não é uma coisa muito gigante a deleção, é essa usando “for”:


ARQS=`ls` ;
for ARQ in $ARQS ; do
rm -rf $ARQ
done ;

Explicando: Jogamos o conteúdo do “ls” em uma variável. Depois rodamos o que tem nessa variável, em loop, e vamos apagando um a um. O problema desta é que depende do espaço em memória que temos disponível. Quanto menos, menos ele faz ou nem consegue alocar memória suficiente para rodar. Serve, mas tem restrições.

Vamos à outra usando “find” e “exec”:


find . -exec rm -rf {} \;

Explicando: “find .” localizará todos os arquivos no diretório do qual está digitando o comando. “-exec”, executará um comando a cara localização de arquivo, neste caso, executará um “rm -rf”. As chaves “{}” inserem o que foi localizado naquela posição, ficando, como exemplo, “rm -rf arquivo_a.txt”. O “\;” está escapando o “;” para o comando “rm” não para o “find”.

Tem esse usando “-delete”:


find . -type f -print -delete

Explicando: “find .” localizará todos os arquivos no diretório do qual está digitando o comando. “-type f” selecionará apenas arquivos. “-delete” os apagarão. “-print” enviará para saída padrão o nome de cada arquivo.

Ainda com “find”, podemos usar o “xargs”:


find . | xargs rm -rf

Explicando: “find .” localizará todos os arquivos no diretório do qual está digitando o comando. ” | “, unirá a resposta do “find” à entrada do “xargs”. “xargs” executará o comando “rm -rf” a cada argumento entrado pelo “find”.

Usando “find”, “split”, “for” e “xargs”:


find . > arquivos
split -l 50 arquivos lista.
for A in lista.* do
cat $A | xargs rm -rf
done

Explicando: “find .” localizará todos os arquivos no diretório do qual está digitando o comando e guardará o resultado em um arquivo chamado “arquivos”. “split -l 50 arquivos lista.” lerá o arquivo “arquivos” e dividirá de 50 em 50 arquivos, gerando os arquivos lista.*. “for” lerá cada arquivo redirecionando a saida para o “xargs”, que apagará cada lista de uma vez.

A mais linda, pro final. “rsync”:


mkdir dir_vazio
rsync -a --delete dir_vazio/ dir_com_muitos_arquivos/

Explicando: Criamos um diretório vazio. Sincronizamos o vazio para o cheio, nisso o “rsync” verá que não tem nada no dir fonte e atualizará, pela opção “-delete” o que está com problemas. Essa é de lascar!