Selecionando os arquivos mais recentes e agrupando por nome

2

Eu tenho um diretório contendo arquivos da seguinte estrutura de nomes.

<device>.<yyyy-mm-dd-hh-mm-ss> 

Estou trabalhando em um script que manterá as últimas X cópias desses backups de configuração para cada dispositivo. Que tipo de magia selecionada eu preciso para que isso aconteça?

Eu estava pensando BASH, mas sou realmente agnóstico em termos de linguagem.

    
por Tim Brigham 16.02.2012 / 20:15

3 respostas

1

Os curingas expandem os nomes dos arquivos em ordem lexicográfica. Como seu formato de data corresponde à ordem lexicográfica, sua necessidade resume-se a manter as últimas correspondências X para um caractere curinga (ou todas as correspondências, se houver menos de X). Assumirei que seus backups são os arquivos correspondentes a $device.* , ajuste o padrão conforme necessário.

No zsh:

set -- $device.*
if [[ $# -gt $X ]]; then set -- $@{[-$X,-1]}; fi
cp -- $@ /retain/area/

Em qualquer shell do estilo Bourne (ash, bash, ksh,…):

set -- "$device".*
if [ $# -gt $X ]; then shift $(($#-$X)); fi
cp -- "$@" /retain/area

Se o que você deseja é, de fato, remover arquivos mais antigos, você precisa agir nas primeiras correspondências, exceto X (ou nenhuma correspondência se houver menos que X).

No zsh:

files=($device.*)
rm -f -- $files[1,-$X-1]

Em outros shells:

set -- "$device".*
while [ $# -gt $X ]; do
  rm -- "$1"
  shift
done
    
por 17.02.2012 / 08:41
0

Aproveitando os nomes dos seus arquivos, e ls ordena lexicalmente por padrão:

ls | awk -F . '
    $1 != current_device {
        current_device = $1
        n5[$1] = n4[$1]
        n4[$1] = n3[$1]
        n3[$1] = n2[$1]
        n2[$1] = n1[$1]
        n1[$1] = $0
    }
    END {
        for (device in n1) {
            print n1[device]
            print n2[device]
            print n3[device]
            print n4[device]
            print n5[device]
        }
    }
'

Eu assumo que os nomes dos dispositivos não contêm pontos. Resultados provavelmente não serão classificados

    
por 16.02.2012 / 20:44
0

Pode precisar de algumas alterações, mas:

ls <DEVICE>.* | sort -r | tail -n +<X+1> | xargs echo rm 

Isso irá mostrar a instrução rm, remover o "echo" para deletar diretamente.

    
por 16.02.2012 / 21:54