remove os arquivos mais antigos

9

Estou tentando excluir arquivos antigos do diretório e deixar apenas 3 novos arquivos.

cd /home/user1/test

while [ 'ls -lAR | grep ^- | wc -l' < 3 ] ; do

    rm 'ls -t1 /home/user/test | tail -1'
    echo " - - - "

done

algo está errado com a declaração condicional.

    
por d3vil0 05.04.2012 / 13:04

8 respostas

9

Se você quiser fazer o loop de arquivos, nunca use ls *. tl; dr Existem muitas situações em que você acabaria excluindo o arquivo errado ou até mesmo todos os arquivos.

Dito isto, infelizmente isso é uma coisa complicada para se fazer no Bash. Há uma resposta em pergunta duplicada meu mais antigo find_date_sorted que você pode usar com pequenas modificações:

counter=0
while IFS= read -r -d '' -u 9
do
    let ++counter
    if [[ counter -gt 3 ]]
    then
        path="${REPLY#* }" # Remove the modification time
        echo -e "$path" # Test
        # rm -v -- "$path" # Uncomment when you're sure it works
    fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p
counter=0
while IFS= read -r -d '' -u 9
do
    let ++counter
    if [[ counter -gt 3 ]]
    then
        path="${REPLY#* }" # Remove the modification time
        echo -e "$path" # Test
        # rm -v -- "$path" # Uncomment when you're sure it works
    fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p%pre%' | sort -rz) # Find and sort by date, newest first
' | sort -rz) # Find and sort by date, newest first

* Sem caras de ataque - também usei ls antes. Mas isso não é seguro.

Editar: Novo find_date_sorted com testes unitários.

    
por 05.04.2012 / 13:35
5

Para excluir todos os arquivos, exceto os 3 mais recentes, usando um zsh glob, é possível usar Om (capital O) para classificar os arquivos do mais antigo para o mais novo e um subscrito para obter os arquivos desejados.

rm ./*(Om[1,-4])
#    | ||||  ' stop at the 4th to the last file (leaving out the 3 newest)
#    | |||' start with first file (oldest in this case)
#    | ||' subscript to pick one or a range of files
#    | |' look at modified time
#    | ' sort in descending order
#    ' start by looking at all files

Outros exemplos:

# delete oldest file (both do the same thing)
rm ./*(Om[1])
rm ./*(om[-1])

# delete oldest two files
rm ./*(Om[1,2])

# delete everything but the oldest file
rm ./*(om[1,-2])
    
por 09.10.2014 / 16:30
5

De longe, o método mais fácil é usar o zsh e seus qualificadores de glob : Om para ordenar por idade decrescente (ou seja, a mais antiga primeiro) e [1,3] para reter apenas as três primeiras correspondências.

rm ./*(Om[1,3])

Veja também Como faço para filtrar um glob no zsh para mais exemplos.

Preste atenção ao conselho do l0b0 : seu código irá quebrar horrivelmente se você tiver nomes de arquivos que contenham caracteres especiais de shell.

    
por 06.04.2012 / 02:19
1

Você pode usar a seguinte função para obter o arquivo mais recente em um diretório:

newest_in() 
{ 
    local newest=$1

    for f;do [[ $f -nt $newest ]] && newest="$f"; done;

    printf '%s\n' "$newest"
}

Dê a ele um conjunto diferente de arquivos excluindo o arquivo mais novo após cada iteração.

Dica: Se você mantiver o conjunto inicial de arquivos em uma matriz chamada "$ {files [@]}", salve o índice do arquivo mais recente encontrado e unset 'files[index]' antes do arquivo próxima iteração.

Uso: newest_in [set of files/directories]

Exemplo de saída:

[rany$] newest_in ./*
foo.txt
[rany$]
    
por 28.04.2013 / 10:11
-1

Primeiro, a opção -R é para recursão, o que provavelmente não é o que você deseja - que pesquisará também em todos os subdiretórios. Em segundo lugar, o operador < (quando não está sendo visto como redirecionamento) é para comparação de cadeia de caracteres. Você provavelmente deseja -lt . Experimente:

while [ 'ls -1A | grep ^- | wc -l' -lt 3 ]

Mas eu usaria encontrar aqui:

while [ 'find . -maxdepth 1 -type f -print | wc -l' -lt 3 ]
    
por 05.04.2012 / 13:26
-1

Eu sei que é um pecado para analisar ls , mas e quanto a isso:

find . -type f -maxdepth 1 | xargs ls -ltr | sed '1,3d' | awk '{print $9}' | xargs rm

Um teste rápido com 5 arquivos vazios:

$ >1
$ >2
$ >3
$ >4
$ >5
$ find . -type f -maxdepth 1 | xargs ls -lt | sed '1,3d' | awk '{print $9}' | xargs rm
$ ls -1
3
4
5
    
por 22.04.2012 / 14:09
-2

Este one-liner faz tudo o que eu penso:

ls -t1 /home/user/test | tail -n +4 | xargs -I{} rm -- "{}"
    
por 13.02.2013 / 15:03
-2

Aqui está uma solução:

rm /appserver/webapplogs/$(ls -t1 /appserver/webapplogs/|tail -1)
    
por 27.04.2013 / 16:12

Tags