Remove todos os arquivos, exceto o último arquivo de cada mês

4

Considere um diretório com arquivos de backup do MySQL com timestamps como parte do nome do arquivo:

-rw-rw-r-- 1 ubuntu ubuntu 35856184 Nov 16 16:00 db_2013-11-16_1600.sql
-rw-rw-r-- 1 ubuntu ubuntu 35856915 Nov 16 17:00 db_2013-11-16_1700.sql
-rw-rw-r-- 1 ubuntu ubuntu 35857565 Nov 16 18:00 db_2013-11-16_1800.sql
-rw-rw-r-- 1 ubuntu ubuntu 35858254 Nov 16 19:00 db_2013-11-16_1900.sql
-rw-rw-r-- 1 ubuntu ubuntu 35860276 Nov 16 20:00 db_2013-11-16_2000.sql
-rw-rw-r-- 1 ubuntu ubuntu 35861583 Nov 16 21:00 db_2013-11-16_2100.sql
-rw-rw-r-- 1 ubuntu ubuntu 35863630 Nov 16 22:00 db_2013-11-16_2200.sql
-rw-rw-r-- 1 ubuntu ubuntu 35864868 Nov 16 23:00 db_2013-11-16_2300.sql
-rw-rw-r-- 1 ubuntu ubuntu 35866095 Nov 17 00:00 db_2013-11-17_0000.sql
-rw-rw-r-- 1 ubuntu ubuntu 35887731 Nov 17 01:00 db_2013-11-17_0100.sql
-rw-rw-r-- 1 ubuntu ubuntu 35888871 Nov 17 02:00 db_2013-11-17_0200.sql
-rw-rw-r-- 1 ubuntu ubuntu 35888871 Nov 17 03:00 db_2013-11-17_0300.sql
-rw-rw-r-- 1 ubuntu ubuntu 35889319 Nov 17 04:00 db_2013-11-17_0400.sql

Isso acontece desde setembro de 2012! Preciso excluir todos os backups, exceto o último backup de cada mês. Ou seja, esses arquivos devem ser deixados:

db_2012-09-30_2300.sql
db_2012-10-31_2300.sql
db_2012-11-30_2300.sql
db_2012-12-31_2300.sql
db_2013-01-31_2300.sql
db_2013-02-28_2300.sql
db_2013-03-31_2300.sql
db_2013-04-30_2300.sql
db_2013-05-30_2300.sql
db_2013-06-30_2300.sql
db_2013-07-31_2300.sql
db_2013-08-31_2300.sql
db_2013-09-30_2300.sql
db_2013-10-31_2300.sql
db_2013-11-20_0700.sql # Because this month has not finished yet!

Eu poderia escrever um script Bash / Python para criar listas de cada mês, remover o último item da lista e, em seguida, excluir um a um os arquivos restantes. Como alternativa, o script poderia mover os últimos arquivos de cada mês para um diretório temporário, remover tudo e depois colocar os arquivos de volta.

No entanto gostaria de saber se existe alguma maneira de simplesmente informar rm (ou rm com find e awk e sort ) para ignorar o último arquivo do mês. Existe tal mágica?

Eu reconheço que a vida seria mais fácil se eu pudesse salvar o primeiro arquivo de cada mês (o que seria apenas uma diferença de 1 hora de salvar o último arquivo de cada mês), mas isso não é aceitável para os outros membros da organização que não conseguem ver que isso essencialmente fornece a mesma proteção.

    
por dotancohen 20.11.2013 / 09:44

4 respostas

2

Com o arquivo zz contendo a lista de nomes de arquivos, isso funciona, então apenas substitua cat zz.

cat zz | grep -vF -f <(cat zz|sort -r|uniq -w11)

por exemplo.     echo * .sql | grep -vF -f < (echo * .sql | ord. -r | uniq -w11) | xargs rm

Como é, não funcionará se houver espaços em nomes de arquivos e muito frágeis para o tamanho do nome do arquivo.

    
por 20.11.2013 / 13:23
1

Uma rápida e bruta tentativa de força bruta em um script (pode ser feita em uma linha, mas precisa de dois loops for, então é meio feia em uma linha)

#! /bin/bash

for year in {2012..2013}
do
   for month in {01..12}
   do
      ls db_"$year"-"$month"*.sql 2>/dev/null | sort -r | tail -n +2 | xargs rm -f
   done
done

Isto, obviamente, não assume caracteres especiais / espaços em branco nos nomes dos arquivos, o que parece ser o seu caso.

    
por 20.11.2013 / 17:07
1

Usando a ideia de ricchard removendo tudo, exceto no último mês:

rm -f 'ls *.sql | sort | uniq w11 -D -u'

Para ver o que será eliminado:

ls *.sql | sort | uniq w11 -D -u
    
por 20.11.2015 / 16:25
-3

Eu usaria o find para isso,

algo nos moldes de find "path" -type f -mtime +30 -exec rm {} \;

esse -mtime +30 significa 30 dias, mas isso pode ser alterado facilmente para atender às suas necessidades. Espero que isso ajude

editar como alternativa, você pode configurar uma tarefa Cron com o script acima, em vez disso, use mv para movê-la para um local conveniente.

    
por 20.11.2013 / 09:56

Tags