Como remover os arquivos do mesmo tamanho em um diretório?

1

Eu tenho imagens, preciso excluir alguns arquivos do mesmo tamanho. Mas não é necessário remover todas essas imagens, mas apenas as próximas na fila (em ordem alfabética):

1.png    # 23,5 Kb
2.png    # 24,6 Kb
4.png    # 24,6 Kb > remove
8.png    # 24,6 Kb > remove
16.png   # 23,5 Kb
    
por Max Zueff 19.06.2016 / 15:55

2 respostas

3

Se você está no Linux ou tem acesso a ferramentas GNU, você pode fazer isso:

last=-1; find . -type f -name '*.png' -printf '%f
last=-1; find . -type f -name '*.png' -printf '%f%pre%' | sort -nz | 
    while read -d '' i; do 
        s=$(stat -c '%s' "$i"); 
        [[ $s = $last ]] && rm "$i"; 
    last=$s; 
done
' | sort -nz | while read -d '' i; do s=$(stat -c '%s' "$i"); [[ $s = $last ]] && rm "$i"; last=$s; done

Explicação

  • last=-1 : defina a variável $last para -1 .
  • find . -type f -name '*.png' -printf '%f.png' : encontre todos os arquivos no diretório atual cujo nome termine em sort -gz e imprima seu nome, seguido do caractere NULL .
  • -z : sort -n - entrada separada ( while read -d '' i; do ) numericamente ( -d '' ). Isso resulta em uma lista classificada de nomes de arquivos.
  • s=$(stat -c '%s' "$i"); : leia a lista de nomes de arquivos. O $s define o delimitador de campo como $i , que é necessário para processar corretamente os dados separados por NULL.
  • [[ $s = $last ]] && rm "$i"; : a variável last=$s agora contém o tamanho do arquivo atual ( $last ).
  • %code% : se o tamanho do arquivo atual for igual ao tamanho do último arquivo, exclua o arquivo.
  • %code% : defina %code% para o tamanho do arquivo atual. Agora, se o próximo arquivo tiver o mesmo tamanho, o passo anterior irá apagá-lo.
por 19.06.2016 / 17:12
3

POSIX implementações da opção ls support a -S para fornecer uma listagem ordenada por tamanho (e aparece, classificado por nome dentro de tamanhos iguais). Você poderia canalizar uma listagem em um loop de shell, lembrando o tamanho do item anterior e removendo "duplicatas".

Isso tem o inconveniente de obter o nome do arquivo (se você gosta de usar espaços em seus nomes de arquivos).

Como alternativa, se você usar uma das plataformas (como Linux ou BSD) que tenham um utilitário stat , você poderá usá-la para criar uma listagem de formato fixo com apenas tamanho e nome de arquivo e classificar , colocando-o em um script simples (r) que verifica tamanhos duplicados.

Uma complicação na questão é que o exemplo não usa a ordem de shell para "alfabético", pois 16.png segue 8.png . A opção -g dos utilitários GNU e BSD sort lida com isso (mas não está em POSIX ).

Considerando esses problemas com sort , seu script provavelmente deve obter a lista de nomes classificados (em sua ordem preferida) e usar stat para obter o tamanho de cada arquivo, sucessivamente.

Aqui está um exemplo rápido para ilustrar (com o "rm" alterado para um "echo"), usando o GNU stat :

#!/bin/sh
last=x
# the sed command strips a leading "./", which confuses "sort -g"
find . -name '*.png' |sed -e 's,^./,,' | sort -g | while true
do
    read item
    [ -z "$item" ] && break
    size=$(stat -c '%s' "$item")
    echo "$size>$item"
    if [ "x$size" = "x$last" ]
    then
        echo "rm -f \"$item\""
    fi
    last="$size"
done
    
por 19.06.2016 / 16:05