Encontre pastas de tamanho menor que x e exclua-as

3

Eu quero encontrar todas as pastas (dentro de uma pasta) com menos de 100 MB e excluí-las. Eu realmente não quero usar um script bash. Mas provavelmente há alguma possibilidade de loop de uma linha para fazer isso. Mas infelizmente meu conhecimento de shell não é tão bom

O que eu tentei

 du -sh * | grep -E "^[0-9]{1,2}M" | xargs -0 rm

Isso não funcionará, pois a saída de du -sh * | grep _E ".." parece ser uma única string.

O que eu também tentei é

find . -maxdepth 1 -type d -size 100M [-delete]

Mas eu acho que o sinal -size não é o que estou procurando

    
por Brettetete 27.01.2015 / 03:20

2 respostas

2

A abordagem simples é encontrar todos os diretórios, obter seu tamanho e excluí-los se estiverem abaixo de um determinado limite:

find . -maxdepth 1 -type d | 
  while read dir; do [ $(du -s "$dir") -le 102400 ] && rm -f "$dir"; done

No entanto, isso falhará em nomes de diretório contendo novas linhas ou outros caracteres estranhos. Uma sintaxe mais segura é:

find . -maxdepth 1 -type d -print0 | while IFS= read -r -d '' dir; do
    [ $(du -s "$dir") -le 102400 ] && rm -f "$dir"
done

Como isso processará os subdiretórios antes de seus pais, quando dir1 for processado, dir2 e dir3 já terão sido excluídos, portanto, seu tamanho ficará abaixo do limite e também será removido. Se você realmente quer ou não, isso dependerá do que exatamente você está tentando fazer.

Isso, no entanto, é uma abordagem simplista. Considere o seguinte cenário:

$ tree -h
.
'-- [4.0K]  dir1
    |-- [4.0K]  dir2
    |   '-- [ 80M]  file1
    '-- [4.0K]  dir3
        '-- [ 80M]  file2

3 directories, 2 files

Aqui, temos dois subdiretórios em dir1 , cada um contendo um arquivo de 80M. O comando acima encontrará primeiro dir1 cujo tamanho é > 100M, pelo que não será eliminado. Em seguida, ele encontrará dir1/dir2 e dir1/dir3 e excluirá ambos, pois são < 100M. O resultado final será um dir1 vazio, cujo tamanho, naturalmente, será de < 100M, uma vez que está vazio.

Portanto, essa solução funcionará bem se você tiver apenas um único nível de subdiretórios. Se você tem estruturas de arquivos mais complexas, precisa pensar em como deseja lidar com isso. Uma abordagem seria usar -depth , o que garante que os subdiretórios sejam mostrados primeiro:

find . -depth -maxdepth 1  -type d -print0 | while IFS= read -r -d '' dir; do
    [ $(du -s "$dir") -le 102400 ] && rm -f "$dir"
done

Dessa forma, dir1 será processado depois de dir2 e dir3 , de modo que ficará vazio, falhará no limite e será excluído também. Se você quer ou não, isso dependerá do que exatamente você está tentando fazer.

    
por terdon 02.03.2015 / 17:57
0

Usar du com sinalizador -h para fazer comparação de valor geralmente é uma má ideia.

O comando que você está procurando é:

find . -maxdepth 1 -type d | grep -v ^\.$ | xargs -n 1 du -s | while read size name ; do if [ $size -gt 104857600 ] ; then echo rm -rf $name ; fi done

Explicação:

  • find . -maxdepth 1 -type d encontra todos os subdiretórios do diretório atual
  • grep -v ^\.$ exclui o diretório atual (.)
  • xargs -n 1 passa-os um a um para o próximo comando
  • du -s fornece o espaço de resumo (ou seja, total) dos arquivos nesse diretório
  • while read size name ... done executa um loop sobre sua entrada, lendo o tamanho e o nome de cada diretório
  • o resto é mais ou menos autoexplicativo.

Quando estiver satisfeito com o comando, remova o echo antes de rm -rf

    
por sмurf 27.01.2015 / 04:08