次のディレクトリ構造があるとします。
root
|-- dirA
|-- file.jpg
|-- file-001.jpg <-- dup
|-- file2.jpg
|-- file3.jpg
|-- dirB
|-- fileA.jpg
|-- fileA_ios.jpg <-- dup
|-- fileB.jpg
|-- fileC.jpg
|-- dirC
|-- fileX.jpg
|-- fileX_ios.jpg <-- dup
|-- fileX-001.jpg <-- dup
|-- fileY.jpg
|-- fileZ.jpg
もしそうなら、ルートフォルダがある場合、同じ名前(サフィックスのみが異なる)を持つ重複するエントリをどのように繰り返し見つけることができますか?
名前は任意の文字列にすることができますが、file...
サフィックスは001、002、003などにすることができます。しかし、3桁のパターンと_ios
リテラル(正規表現一致のため)があると仮定するのは安全です。
私のLinux fooはあまり良くありません。
ベストアンサー1
少し長いがコマンドラインです。ファイルの内容を調べて、暗号化ハッシュ()を使用してmd5sum
比較します。
find . -type f -exec md5sum {} + | sort | sed 's/ */!/1' | awk -F\| 'BEGIN{first=1}{if($1==lastid){if(first){first=0;print lastid, lastfile}print$1, $2} else first=1; lastid=$1;lastfile=$2}'
さっき言ったように内容がちょっと長いです…
find
md5sum
現在のディレクトリツリー内のすべてのファイルに対して実行されます。その後、出力はsort
md5ハッシュを介して行われます。ファイル名にスペースがある可能性があるため、最初のフィールドsed
区切り文字(スペース2つ)を垂直パイプ(ファイル名に表示される可能性が低い)に変更します。
最後のawk
コマンドは、3 つの変数、つまり = 前lastid
のエントリの md5 ハッシュ、 = 前のlastfile
エントリのファイル名、first
= 最初に表示された最後の ID を追跡します。
出力にはハッシュが含まれており、どのファイルが互いに重複しているかを確認できます。
これは、ファイルがハードリンク(同じinode、別名)かどうかを示さず、内容のみを比較します。
更新:ファイルのデフォルト名のみに基づいて変更します。
find . -type f -print | sed 's!.*/\(.*\)\.[^.]*$!\1|&!' | awk -F\| '{i=indices[$1]++;found[$1,i]=$2}END{for(bname in indices){if(indices[bname]>1){for(i=0;i<indices[bname];i++){print found[bname,i]}}}}'
ここでは、find
ファイル名をリストし、パス名sed
のデフォルト名部分を取り、ベース名とフルパス名を含む2フィールドテーブルを作成します。その後、awk
見たパス名(「発見」)テーブルが作成され、デフォルト名とエントリ番号でインデックスが作成されます。 「インデックス」配列は、見たデフォルト名の数を追跡します。次に、「END」句は、見つかった重複したデフォルト名を印刷します。