Remover primeira instância de linhas com valor de campo duplicado

1

Eu chamei sha1 todos os arquivos de imagem no meu servidor de armazenamento e coloquei os resultados em um arquivo de texto na forma de:

nome do arquivo sha1sum

Classifiquei o arquivo e removi todas as entradas únicas do sha1sum. Então, o que me resta é uma lista de arquivos duplicados. Alguns têm duas entradas, algumas três e outras ainda.

O que eu quero fazer é remover somente a primeira entrada de cada sha1sum duplicado, para que eu possa usar a saída resultante para excluir os arquivos duplicados (e manter apenas uma instância de cada)

Eu realmente não me importo com qual versão será mantida, pois irei mover todos os arquivos para alguma forma de hierarquia de diretórios depois

    
por Graeme Russ 21.05.2012 / 02:36

2 respostas

4

Com os utilitários GNU, como encontrados no Linux ou no Cygwin, você pode dizer ao uniq para separar cada bloco de arquivos com o mesmo hash. Chamar uniq com a opção --all-repeated remove arquivos exclusivos da lista no processo.

sha1sum * |
sort | uniq -w 40 --all-repeated=prepend |
sed -e '/^$/ { N; d; }' -e 's/^[^ ]*  //' |
tr '\n' '
sha1sum * |
sort |
awk '$1==h {print}  {h=$1}' |
tr '\n' '
fdupes -f
' | xargs -0 rm --
' | xargs -0 rm --

Isso não vale o esforço em relação a este script awk simples e portátil: imprima cada linha se seu primeiro campo for idêntico ao primeiro campo da linha anterior. Novamente, isso resolve remover arquivos exclusivos da lista.

sha1sum * |
sort | uniq -w 40 --all-repeated=prepend |
sed -e '/^$/ { N; d; }' -e 's/^[^ ]*  //' |
tr '\n' '
sha1sum * |
sort |
awk '$1==h {print}  {h=$1}' |
tr '\n' '
fdupes -f
' | xargs -0 rm --
' | xargs -0 rm --

Em vez de fazer isso manualmente, você pode ligar para fdupes .

%pre%     
por 21.05.2012 / 03:01
1

Você também pode usar awk 'a[$1]++'

$ gsha1sum *
86f7e437faa5a7fce15d1ddcb9eaeaea377667b8  file1
e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98  file2
86f7e437faa5a7fce15d1ddcb9eaeaea377667b8  file3
86f7e437faa5a7fce15d1ddcb9eaeaea377667b8  file4
$ gsha1sum *|awk 'a[$1]++'
86f7e437faa5a7fce15d1ddcb9eaeaea377667b8  file3
86f7e437faa5a7fce15d1ddcb9eaeaea377667b8  file4

Como os comandos postados por Gilles, também remove linhas cujo primeiro campo aparece apenas uma vez na entrada.

a[$1]++ pode ser substituído por a[$1]++>0 ou ++a[$1]>=2 .

    
por 09.06.2014 / 03:21