Exclua todos os arquivos (exceto os quatro mais recentes) em todos os diretórios usando um script Bash

7

Estou procurando um script Bash que vá para uma lista de diretórios e exclua todos, exceto os quatro arquivos criados mais recentemente.

Como posso fazer isso?

    
por Marv1n 16.08.2011 / 05:41

5 respostas

6

ls -t | sed '1,4d' | xargs echo rm

Remova o echo quando estiver satisfeito com o resultado desejado.

Se você tem nomes de arquivos com espaços, mais trabalho é necessário.

    
por 16.08.2011 / 05:53
0

Você deseja manter os quatro arquivos mais recentes em cada diretório ou os quatro arquivos mais recentes em QUALQUER diretório?

Para resolver o primeiro problema, você usaria find para listar cada diretório e, em cada um, remover todos, exceto os quatro arquivos mais recentes. Isso não é muito difícil.

Resolver o segundo problema leva um pouco mais de reflexão, mas é realmente mais fácil de escrever.

Basicamente, encontre todos os arquivos de forma recursiva. Chame o comando "stat" retornando a hora e o nome da modificação do arquivo. Classifique isso descendo numericamente e pule os quatro primeiros arquivos, que são os mais recentes.

Em seguida, remova os timbres iniciais e remova a lista de nomes de arquivos resultante.

Algo como (não testado):

#!/bin/bash

find "$@" -type f -print0 \
| xargs -0 stat -c$'%Y\t%n' \
| sort -rn \
| awk -F$'\t' 'NR > 4 {print $2}' \
| while read f; do
    echo rm -v "${f}"
  done

Isso deve funcionar, embora você queira remover o 'eco' no loop while para torná-lo efetivo. Teste com cuidado primeiro!

    
por 17.08.2011 / 08:53
0

Eu sei que isso não é exatamente o que você está perguntando, mas para esse tipo de backup eu prefiro girar os arquivos de log antes de criar o novo. É um pouco mais explícito e muito mais simples de codificar, assim:

#!/bin/bash

#Archive old backups
move () {
  if [ -e $1 ]
  then
    echo "Archiving old backups: $1 to $2"
    mv -f $1 $2 || echo "FAILED"
  fi
}

#Bump each backup +1
rm -rf backup.4
move backup.3.tgz backup.4.tgz
move backup.2.tgz backup.3.tgz
move backup.1.tgz backup.2.tgz
move backup.tgz backup.1.tgz

#Now create today's backup
...
    
por 13.09.2011 / 12:47
0

Este comando deve funcionar

find PATH1 PATH2 PATH3 -type f  -printf '%T@ %p\n'|sort -nr|tail -n+5|cut -f 2- -d " "|xargs -i rm {}

Se você não quiser que o comando exclua arquivos recursivamente, adicione a opção -maxdepth 1 antes de -type f

O comando imprime recursivamente cada arquivo com sua última data de modificação ( find PATH1 PATH2 PATH3 -type f -printf '%T@ %p\n' ), depois ordena a lista por data ( sort -nr ) e, em seguida, ignora as quatro primeiras entradas ( tail -n+5 ). Finalmente, as informações de tempo são removidas ( cut -f 2- -d " " ) e o resultado subsequentemente passado para xargs que gera e executa o comando rm correspondente.

    
por 16.09.2011 / 10:37
0

O método mais simples:

for d in dir1 dir2 dir3; do
  rm -vf 'ls -1t $d | head -n-4' 
done
    
por 30.09.2011 / 20:06