Nome de arquivo exclusivo para arquivos diferentes

3

Estou trabalhando com design gráfico. Eu baixei muitos arquivos ( EPS arquivos, PSD arquivos, etc) de vários sites.

Como vem de vários sites, depois de baixados de mais de 10 sites diferentes, recebi muitos arquivos iguais com o mesmo tamanho e o mesmo nome de arquivo diferente (de 2 a 4 cópias para o mesmo arquivo). Para remover a duplicação manualmente, abrir um por um é muito demorado

Espero que haja uma maneira de renomear todos os arquivos baixados para serem um nome exclusivo para arquivos diferentes (não me importo se o novo nome não for descritivo).

Por exemplo, 2 mesmo arquivo: arquivo nice-sun.eps baixado do site 1, enquanto 678.eps baixado do site 2. Ele se tornará o mesmo nome de arquivo depois de renomeado.

    
por apasajja 23.04.2012 / 06:51

3 respostas

6

Este comando irá renomear todos os arquivos para o md5sum do seu conteúdo. Isso significa que arquivos com o mesmo conteúdo receberão o mesmo nome.

for f in *; do mv $f $(md5sum $f | cut -d " " -f 1); done

Você pode substituir md5sum por sha1sum no comando.

Para esta demonstração, adicionei -v a mv , para que possamos ver o que está sendo renomeado.

$ echo 1 > a
$ echo 2 > b
$ echo 1 > c
$ ls -1
a
b
c
$ for f in *; do mv -v $f $(md5sum $f | cut -d " " -f 1); done
'a' -> 'b026324c6904b2a9cb4b88d6d61c81d1'
'b' -> '26ab0db90d72e28ad0ba1e22ee510510'
'c' -> 'b026324c6904b2a9cb4b88d6d61c81d1'
$ ls -1
26ab0db90d72e28ad0ba1e22ee510510
b026324c6904b2a9cb4b88d6d61c81d1

Você também pode executar esse comando com segurança em um diretório em que alguns arquivos tenham o nome do arquivo unificado, enquanto outros não.

$ echo 1 > d
$ echo 2 > e
$ ls -1
26ab0db90d72e28ad0ba1e22ee510510
b026324c6904b2a9cb4b88d6d61c81d1
d
e
$ for f in *; do mv -v $f $(md5sum $f | cut -d " " -f 1); done
mv: '26ab0db90d72e28ad0ba1e22ee510510' and '26ab0db90d72e28ad0ba1e22ee510510' are the same file
mv: 'b026324c6904b2a9cb4b88d6d61c81d1' and 'b026324c6904b2a9cb4b88d6d61c81d1' are the same file
'd' -> 'b026324c6904b2a9cb4b88d6d61c81d1'
'e' -> '26ab0db90d72e28ad0ba1e22ee510510'
$ ls -1
26ab0db90d72e28ad0ba1e22ee510510
b026324c6904b2a9cb4b88d6d61c81d1

Observe que ele ainda calculará o hash dos arquivos que já estão em hash. Então, se os arquivos são enormes, você pode querer evitar o rehashing.

    
por 23.04.2012 / 09:38
3

Este é o script rename-hash que uso para renomear arquivos para o hashsum, mantendo a extensão inalterada. Leva uma lista de arquivos a serem renomeados como parâmetros. Use -n como primeiro parâmetro para execução a seco.

#!/bin/sh

unset DRY
[ "$1" == "-n" ] && { DRY=1; shift; }

for i in $@; do

if [ -f "$i" ]; then

HASHSUM=$(md5sum "$i" | sed 's/\(..........\).*//')
DIR=$(dirname "$i")
BASE=$(basename "$i")
EXT=$(echo "$BASE" | sed -n 's/[^.]*\(\..*\)//p')
TARGET="$DIR"/"$HASHSUM""$EXT"
if [ "$TARGET" != "$DIR/$BASE" ]; then
   if [ -n "$DRY" ]; then
       echo will rename "$i" to "$TARGET"
   else
       mv "$i" "$TARGET"
   fi
fi

fi

done

Exemplo:

$ rename-hash -n *
will rename test.pdf to ./f604d0d6ad.pdf
will rename images.tar.gz to ./d41d8cd91b.tar.gz
    
por 23.04.2012 / 10:07
0

Existem alguns utilitários para encontrar duplicatas. Você pode usar find e md5sum, mas isso pode levar muito tempo.

Eu costumo usar fdupes para isso. Se pode encontrar todos os duplicados e saída seus nomes para stdout. Depois disso, você pode analisar a saída e renomear todos os arquivos como quiser ou até mesmo removê-los.

    
por 23.04.2012 / 09:25