我有一个包含文件路径及其 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