按列查找檔案中的重複項

按列查找檔案中的重複項

我有一個包含文件路徑及其 md5sum 的輸入文件,用分號分隔並按 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

我想知道如何根據哈希找到重複項並列印它們,因此上述輸入的輸出如下所示:

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

我嘗試過uniq,但找不到如何將其欄位分隔符號從空格變更為分號(某些檔案路徑中可能有空格)

答案1

如果您的路徑不包含空格或分號,只需將分號變成空格即可。

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

如果您的路徑包含空格但不包含製表符或分號,則您可以執行基本上相同的操作 - 但暫時將空格變成分號,並使用製表符作為欄位分隔符號。

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

如果您不想對檔案名稱做出任何假設(除了不包含換行符之外),您可以讓 awk 來完成這項工作。

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

答案2

可能的解決方案可以使用以下方法awk

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

需要注意的是檔案會被讀取兩次。在第一遍中,我們計算重複次數並將其儲存在數組中,在第二遍中,如果計數器大於 1,我們將列印行。

答案3

非常簡單perl(為了獎勵積分 - 你md5sum也可以這樣做)。

但像這樣的事情:

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

注意<>是神奇的文件句柄。它透過STDIN命令列或從檔案將資料傳輸到腳本中./myscript.pl file_containing_data

答案4

在更聰明的解決方案中,這裡有一個強力的“one-liner”,它cut輸出 md5sum,運行它uniq -c以獲取計數,用於awk修剪掉實際唯一的值,然後將剩餘的 md5sum 通過for循環傳遞到grep匹配值從原始文件。當然不如 Gilles 的全 awk 解決方案那麼優雅,而且還存在讀取輸入檔兩次的缺點。

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

我在您的範例輸入檔中新增了額外的重複:

/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

上述循環產生:

/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

相關內容