Eu tenho um arquivo de entrada contendo caminhos de arquivo e seu md5sum, separados por ponto e vírgula e classificados por hashes md5:
/media/LaCie/Images/recup2/recup_dir.1/f1295328.jpg;0080ececd3da8533f5d11e449cf73287
/media/LaCie/Documents/pics/897_FUJI/DSCF7042.JPG;0081cd15705f0c541995e13ad3e405b8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387
Gostaria de saber como encontrar duplicatas com base no hash e imprimi-las, para que a saída da entrada acima fique assim:
/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387
Eu tentei uniq
, mas não consegui descobrir como alterar o separador de campos de espaços para ponto e vírgula (alguns caminhos de arquivo podem conter espaços)
Responder1
Se seus caminhos não contiverem espaços ou ponto e vírgula, basta transformar os pontos e vírgulas em espaços.
tr ';' ' ' | uniq -f 1 -d | tr ' ' ';'
Se seus caminhos contiverem espaços, mas não tiverem tabulações ou ponto e vírgula, você poderá fazer basicamente a mesma coisa - mas transformar temporariamente os espaços em ponto e vírgula e usar uma tabulação como separador de campo.
tr '; ' '\t;' | uniq -f 1 -d | tr '\t;' '; '
Se você não quiser fazer nenhuma suposição sobre os nomes dos arquivos (além de não conter novas linhas), você pode fazer com que o awk faça o trabalho.
awk -F ';' '{
if ($NF == current) {
if (first != "") print first;
first = "";
print;
} else {
first = $0;
current = $NF;
}
}'
Responder2
A solução possível poderia ser usar o seguinte awk
:
awk -F";" 'FNR == NR { x[$2]++; next; } { if ($2 in x && x[$2] > 1) print; }' file file
A advertência é que o arquivo é lido duas vezes. Na primeira passagem contamos e armazenamos as repetições no array e na segunda passagem imprimimos a linha se o contador for maior que 1.
Responder3
Muito fácil perl
(para ganhar pontos extras - você md5sum
também pode fazer a parte).
Mas algo assim:
#!/usr/bin/env perl
use strict;
use warnings;
my %file_md5;
while ( <> ){
chomp;
my ( $filename, $hash ) = split /;/;
if ( $file_md5{$hash} ) {
print "$filename has the same md5sum as $file_md5{$hash}\n";
}
$file_md5{$hash} = $filename;
}
Nota <>
é o identificador de arquivo mágico. Leva dados canalizados para o script por meio STDIN
de arquivos na linha de comando./myscript.pl file_containing_data
Responder4
Entre as soluções mais inteligentes, aqui está uma "linha única" de força bruta que cut
elimina o md5sum, executa-o uniq -c
para obter as contagens, usa awk
para eliminar os valores realmente exclusivos e, em seguida, passa os md5sums restantes por meio de um for
loop para grep
os valores correspondentes do arquivo original. Certamente não é tão elegante quanto a solução totalmente awk de Gilles e também tem a desvantagem de ler o arquivo de entrada duas vezes.
for md5 in $(cut -d\; -f2 inputfile-here | uniq -c | awk '$1 > 1 { print $2 }')
do
grep ";$md5\$" inputfile-here
echo ## gratuitous blank line to separate the duplicates
done
Adicionei duplicatas extras ao seu arquivo de entrada de amostra:
/media/LaCie/Images/recup2/recup_dir.1/f1295328.jpg;0080ececd3da8533f5d11e449cf73287
/media/LaCie/Documents/pics/897_FUJI/DSCF7042.JPG;0081cd15705f0c541995e13ad3e405b8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729-1.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729-2.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387
para o qual o loop acima produz:
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729-1.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Documents/Pictures/124_FUJI/DSCF4729-2.JPG;00829232ae6b181654ee87ff32d161f8
/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387