Buscar duplicados por columna en un archivo

Buscar duplicados por columna en un archivo

Tengo un archivo de entrada que contiene rutas de archivo y su suma md5, separadas por punto y coma y ordenadas 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

Me gustaría saber cómo puedo encontrar duplicados basados ​​en el hash e imprimirlos, de modo que el resultado de la entrada anterior se vea así:

/media/LaCie/Images/Trashes/501/IMG_0651.JPG;00833c74523d5361641af863f5d92387
/media/LaCie/Images/2009-09/IMG_0651.JPG;00833c74523d5361641af863f5d92387

Lo intenté uniq, pero no pude encontrar cómo cambiar su separador de campos de espacios a punto y coma (algunas rutas de archivos pueden tener espacios)

Respuesta1

Si sus rutas no contienen espacios ni punto y coma, simplemente convierta los puntos y coma en espacios.

tr ';' ' ' | uniq -f 1 -d | tr ' ' ';'

Si sus rutas contienen espacios pero no tabulaciones ni punto y coma, puede hacer básicamente lo mismo, pero convertir temporalmente los espacios en punto y coma y utilizar una tabulación como separador de campos.

tr '; ' '\t;' | uniq -f 1 -d | tr '\t;' '; '

Si no desea hacer ninguna suposición sobre los nombres de los archivos (aparte de que no contienen nuevas líneas), puede hacer que awk haga el trabajo.

awk -F ';' '{
    if ($NF == current) {
        if (first != "") print first;
        first = "";
        print;
    } else {
        first = $0;
        current = $NF;
    }
}'

Respuesta2

Una posible solución podría ser utilizar lo siguiente awk:

awk -F";" 'FNR == NR { x[$2]++; next; } { if ($2 in x && x[$2] > 1) print; }' file file

La advertencia con esto es que el archivo se lee dos veces. En la primera pasada contamos y almacenamos las repeticiones en una matriz y en la segunda pasada imprimimos la fila si el contador es mayor que 1.

Respuesta3

Es bastante fácil (para obtener puntos de bonificación, también perlpuedes hacer la parte).md5sum

Pero algo como esto:

#!/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;
}

La nota <>es el identificador de archivo mágico. Toma datos canalizados al script a través de STDINo desde archivos en la línea de comando./myscript.pl file_containing_data

Respuesta4

Entre las soluciones más inteligentes, aquí hay una "línea única" de fuerza bruta que cutextrae la suma md5, la ejecuta uniq -cpara obtener los recuentos, la utiliza awkpara eliminar los valores realmente únicos y luego pasa las sumas md5 restantes a través de un forbucle hasta greplos valores coincidentes. del archivo original. Ciertamente no es tan elegante como la increíble solución de Gilles, y también tiene la desventaja de leer el archivo de entrada dos veces.

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

Agregué duplicados adicionales a su archivo de entrada de muestra:

/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

a lo que el bucle anterior produce:

/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

información relacionada