セミコロンで区切られ、md5ハッシュでソートされたファイルパスと、対応するmd5sumを含む入力ファイルがあります。
/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
ファイルを2回読みます。最初のパスでは繰り返し回数を数えて配列に保存し、2番目のパスではカウンタが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
cut
よりスマートなソリューションには、md5sumを出力してそれを実行して実際の固有値を切り取るuniq -c
ためのカウントを取得し、残りのawk
md5sumをfor
ループを通過してgrep
次の値と一致させる無差別の「ワンライナー」があります。元のファイル。確かにGillesのall-awkソリューションほどエレガントではなく、入力ファイルを2回読み取るという欠点があります。
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