Mantendo as últimas duas versões e excluindo as restantes

1

Eu tenho uma lista de arquivos (digamos, o formato xsl abaixo) em um diretório. Eu quero manter as últimas duas versões de todos os arquivos. (Eu posso deletar os arquivos restantes)

{A}_1.0.xsl
{A}_2.0.xsl
{A}_3.0.xsl
{A}_4.1.xsl
{A}_5.0.xsl
{A}_6.0.xsl
{B}_1.0.xsl
{B}_2.0.xsl
{B}_3.0.xsl
{B}_4.0.xsl
{C}_1.0.xsl
{C}_2.0.xsl
{C}_3.0.xsl

Os arquivos restantes presentes no diretório devem ser

{A}_5.0.xsl
{A}_6.0.xsl
{B}_3.0.xsl
{B}_4.0.xsl
{C}_2.0.xsl
{C}_3.0.xsl

Como pode ser alcançado?

    
por ahamedirshad123 18.01.2014 / 18:27

2 respostas

4

Supondo que todos os nomes de arquivos no diretório atual sigam esse padrão, com GNU ls:

ls -rv | awk -F_ '++n[$1]>2' | xargs rm

Você pode omitir o | xargs rm se quiser verificar o que removeria primeiro .

Isso pressupõe que a parte em {...} não contenha espaço, nova linha, aspas simples, aspas duplas, barra invertida, tabulações ou caracteres de sublinhado.

A chave é a opção -v para a implementação GNU de ls que ordena por número de versão. Se você não tem o GNU ls , mas tem zsh , em zsh você pode usar:

print -rl -- *(nOn)

Para alcançar o mesmo resultado.

Agora, se o diretório atual puder conter qualquer coisa e você quiser processar apenas os arquivos que estão no formato {x}_y.z.xsl , em que x pode ser qualquer coisa e y e z são números inteiros decimais positivos, teria que escrevê-lo ( zsh syntax):

printf '%s
eval "files=($(ls -rv --quoting-style=shell-always))"
printf '%s
ls -rv | awk -F_ '++n[$1]>2' | xargs rm
' "${files[@]}" | perl -0 -lne ' unlink if /^\{(.*)\}_\d+\.\d+\.xsl\z/s && ++$n{$1} > 2'
' \{*\}_<->.<->.xsl(.nOn) | perl -0 -lne ' unlink if /\{.*\}/s && ++$n{$&} > 2'

Ou usando GNU ls e GNU bash em vez de zsh :

print -rl -- *(nOn)
    
por 18.01.2014 / 19:53
-1
for i in 'ls *_*.?.xsl | sed -n 's/\(.*_\)[0-9]\+\.[0-9]\.xsl//p' | uniq' ; \
do ls $i*.?.xsl | tac | sed 1,2d | xargs rm; done

Isso faz o seguinte

  • Encontre o prefixo para os diferentes conjuntos de arquivos (por exemplo, {A} , {B} etc)
  • Para cada prefixo, liste todos os arquivos e exclua as duas últimas entradas (feito invertendo a lista e excluindo as duas primeiras entradas)
  • Execute rm para os arquivos na lista restante

Isso se baseia no pressuposto de que a ordem de classificação alfabética é a mesma que a ordem cronológica. Talvez isso não seja exatamente o que você está procurando, mas o princípio de excluir tudo, exceto as duas últimas entradas (para algum tipo de ordem de classificação) deve ser o mesmo.

    
por 18.01.2014 / 19:16