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.
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?
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.
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!
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
...
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.
O método mais simples:
for d in dir1 dir2 dir3; do
rm -vf 'ls -1t $d | head -n-4'
done
Tags bash linux bash-scripting