Trouver les doublons par colonne dans un fichier

3

J'ai un fichier d'entrée contenant les chemins de fichiers et leur somme md5, séparés par des points-virgules et triés par hachage 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

J'aimerais savoir comment je pourrais trouver des doublons basés sur le hachage et les imprimer, pour que la sortie de l'entrée ci-dessus ressemble à ceci:

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

J'ai essayé uniq, mais je n'ai pas trouvé comment changer le séparateur de champs d'espaces en points-virgules (certains chemins de fichiers peuvent contenir des espaces)

l0r3nz4cc10
la source
Si l’une des réponses existantes résout votre problème, envisagez de l’accepter avec la coche. Je vous remercie!
Jeff Schaller

Réponses:

3

Si vos chemins ne contiennent pas d'espaces ou de points-virgules, il suffit de les transformer en espaces.

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

Si vos chemins contiennent des espaces mais pas de tabulations ni de points-virgules, vous pouvez faire la même chose, mais transformer temporairement les espaces en points-virgules et utiliser un onglet comme séparateur de champs.

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

Si vous ne voulez pas faire d'hypothèses sur les noms de fichiers (autres que ne pas contenir de nouvelles lignes), vous pouvez faire en sorte que awk fasse le travail à la place.

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

La solution possible pourrait être la suivante awk:

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

La mise en garde avec ceci est que le fichier est lu deux fois. Lors de la première passe, nous comptons et stockons les répétitions dans un tableau et lors de la deuxième passe, nous imprimons une ligne si le compteur est supérieur à 1.

taliézine
la source
0

Assez facile avec perl(pour les points de bonus - vous pouvez faire la même chose md5sum).

Mais quelque chose comme ça:

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

Remarque <>est le descripteur de fichier magique. Il faut des données contenues dans le script via STDINou à partir de fichiers en ligne de commande./myscript.pl file_containing_data

Sobrique
la source
0

Parmi les solutions les plus intelligentes, voici un "one-liner" de force brute qui se trouve cutdans le md5sum, l'exécute uniq -cpour obtenir les comptes, l'utilise awkpour éliminer les valeurs réellement uniques, puis passe les md5sums restants via une forboucle aux grepvaleurs correspondantes à partir du fichier d'origine. Certainement pas aussi élégant que la solution tout-générique de Gilles, et a également le malheur de lire le fichier d'entrée deux fois.

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

J'ai ajouté des doublons supplémentaires à votre exemple de fichier d'entrée:

/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

à laquelle la boucle ci-dessus produit:

/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
Jeff Schaller
la source