重複するファイルをハードリンクに置き換える簡単な方法はありますか?


136

find2つのディレクトリで重複フ​​ァイルを見つけ、1つのディレクトリのファイルを別のディレクトリのファイルのハードリンクで置き換える簡単な方法(コマンドまたは一連のコマンド、おそらくを含む)を探しています。

状況は次のとおりです。これは、複数の人がオーディオファイルを保存するファイルサーバーで、各ユーザーが独自のフォルダーを持っています。複数の人がまったく同じ音声ファイルのコピーを持っている場合があります。現在、これらは重複しています。ハードドライブのスペースを節約するために、それらがハードリンクになるようにしたいと思います。


20
ハードリンクで遭遇する可能性のある問題の1つは、誰かが自分の音楽ファイルの1つに何かを行うことを決めた場合、あなたが誤って他の人の音楽へのアクセスに影響を与える可能性があることです。
スティーブンD

4
もう1つの問題は、「Some Really Great Tune」を含む2つの異なるファイルが、同じエンコーダーで同じソースから取得されたとしても、ビットごとに同一ではない可能性が高いことです。
msw

3
より良いsollutionは公共音楽フォルダを持っているかもしれない
ステファン・


1
@tante:シンボリックリンクを使用しても問題は解決しません。ユーザーがファイルを「削除」すると、そのファイルへのリンクの数が減り、カウントがゼロに達すると、ファイルが実際に削除されます。それだけです。そのため、ハードリンクファイルでは削除は問題ありません。唯一の問題は、ユーザーがファイルを編集しようとする(実際にはありえない)か、ファイルを上書きしようとする(ログインすると可能になる)ことです。
maaartinus

回答:


41

http://cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.plにはperlスクリプトがあります。

コマンドラインで指定されたすべてのディレクトリを走査し、MD5チェックサムを計算し、同一のMD5を持つファイルを見つけます。それらが等しい場合、実際に等しい場合は実際の比較を行い、2つのファイルの2番目のファイルを最初のファイルへのハードリンクに置き換えます。


サウンド完璧な、ありがとう!試してみて、説明どおりに機能する場合は受け入れます!
ジョシュ

3
これはまさに私が求めていたものでした。ただし、ファイルにわずかな違いがあり、ハードリンクできるのはごくわずかであることがわかったため、Dedupを使用したZFSが最終的に行う方法になると考えています。
ジョシュ

11
これを支持しましたが、さらに調査した後、私はそうしませんでした。rdfindすべての主要プラットフォーム(os x、linux、(cyg)win、solaris)のパッケージマネージャーを介して利用でき、非常に速いネイティブスピードで動作します。以下の回答をご覧ください。
オリゴフレン

@oligofren私は同じことを考えていましたが、その後ヒットしました[Errno 31] Too many links。このスクリプトは、それを処理する唯一のものであると思われます。
プネヘヘ

5
同一サイズの他のファイルが少なくとも1つ存在するファイルだけでなく、すべての単一ファイルをチェックサムすることは、不必要に非効率的です(また、不必要にハッシュ衝突が発生しやすくなります)。
チャールズダフィー

85

rdfindまさにあなたが求めることを行います(そしてjohny whyリストの順に)。重複を削除し、ソフトリンクまたはハードリンクのいずれかに置き換えることができます。組み合わせることでsymlinks、あなたもシンボリックリンクが絶対的または相対することができます。チェックサムアルゴリズム(md5またはsha1)を選択することもできます。

コンパイルされているため、ほとんどのスクリプトソリューションよりも高速です。time2009年のMac Miniの2600ファイルの15 GiBフォルダーでは、これが返されます

9.99s user 3.61s system 66% cpu 20.543 total

(md5を使用)。

ほとんどのパッケージハンドラー(Mac OS X用のMacPortsなど)で利用できます。


11
+1私rdfindはそれを使い、愛していました。それは-dryrun trueあなたがそれがしたであろうことを知らせるオプションがあります。重複をハードリンクに置き換えるのは、と同じくらい簡単-makehardlinks trueです。素敵なログが生成され、空きスペースがどれだけあるかがわかりました。さらに、著者のベンチマークによると、rdfindはduffやfslintよりも高速です。
ダニエルトレビエン

ああ、いいね。以前はfdupesを使用していましたが、最新のUbuntu 14.10では、重複リンクのハードリンク用の-Lオプションがありません。かなり遅く、OSXのHomebrewには存在しなかったので、この答えの方がずっと良いです。ありがとう!
オリゴフレン

非常にスマートで高速なアルゴリズム。
-ndemou

2
このツールのパフォーマンスは、アルゴリズム自体に関係があり、コンパイルされたツールであるか、スクリプトであるかに関係があるとは思いません。この種の操作では、ほとんどの場合、ディスクがボトルネックになります。スクリプトツールは、チェックサムでCPUを焼き付けながら非同期I / O操作が進行中であることを確認している限り、ネイティブバイナリと同等のパフォーマンスを発揮する必要があります。
cdhowie

rdfindは、新しいOSとコンパイラに大きく依存しています。(開発ツールをほぼ完全に再構築しない限り、CentOS 6.xでは実行できません)
Cosmo F

49

fdupesツールを使用します。

fdupes -r /path/to/folderディレクトリ内の重複のリストが表示されます(-rにより再帰的になります)。出力は次のようになります。


filename1
filename2

filename3
filename4
filename5


filename1とfilename2は同一であり、filename3、filename4およびfilename5も同一です。


1
Ubuntu注:2013年9月の時点では、安定リリース(1.50-PR2-3)ではないため、ubuntuにはまだアップデートが表示されていません。
スチュアートアクソン

11
UbuntuとDebianの両方にfdupes_1.50-PR2-4をインストールしようとしましたが、どちらにも-Lフラグがありません。幸いなことにgithub.com/tobiasschulz/fdupesからの構築は非常に簡単でした。
neu242

3
試してみてくださいrdfind-のようfdupesですが、OS XとCygwinでも高速で利用可能です。
オリゴフレン

6
fdupes重複を見つけるだけで、ハードリンクで置き換えるのではなく、IMOの質問に対する答えではないようです。
カリモ

2
jdupes基づいたと呼ばれる同様のツールがありfdupesますが、重複ファイルをシンボリックリンク(-l)、ハードリンク()で置き換え-Lたり、btrfsにファイルシステムレベルでブロックを重複排除するよう指示することもできます(btrfsを-B使用している場合)。
マリウスゲドミナス

23

私はhttp://jak-linux.org/projects/hardlink/hardlinkから使用します


1
ニースのヒントは、私は定期的なベースに使用していますcode.google.com/p/hardlinkpy ...しかし、これはしばらく更新されませんでした
meduz

2
これhardlinkはFedora / RHEL / etcのオリジナルに似ているようです。

1
hardlink現在、多くのLinuxパッケージシステムのネイティブバイナリ(〜2014以降)および非常に高速です。1,2Mファイル(320GB)の場合、200秒かかりました(ファイルの約10%をリンクします)。
マルセル・ヴァルトフォーゲル

FWIW、上記hardlinkはJulian Andres Klodeによって作成され、Fedora hardlinkはJakub Jelinekによって作成されました(ソース:pagure.io/hardlink-Fedoraパッケージ名:
hardlink

18

これは「fslint」によって提供される機能の1つです。http: //en.flossmanuals.net/FSlint/Introduction

[結合]ボタンをクリックします。

スクリーンショット


4
-mは、一緒に重複をハードリンクされます、-d 1以外のすべてを削除し、-tは、実行を乾燥します、それはどうなるのか印刷
Azendale

1
Ubuntuではここで何をするかである:sudo apt-get install fslint /usr/share/fslint/fslint/findup -m /your/directory/tree(ディレクトリを/ usr / share / fslint / fslint /デフォルトでは$ PATHにありません)
ジョセリン

14

主な目的はディスク容量を節約することなので、別の解決策があります。ファイルシステムレベルでの重複排除(およびおそらく圧縮)です。ハードリンクソリューションと比較して、他のリンクファイルに誤って影響を与える問題はありません。

ZFSには、プールバージョン23以降の重複除去(ファイルレベルではなくブロックレベル)と、かなり前からの圧縮があります。Linuxを使用している場合は、zfs-fuseを試すことができます。BSDを使用している場合は、ネイティブにサポートされています。


これはおそらく私が最終的に行く方法ですが、BSDのZFS実装は削除されますか?私はそうは思わなかった。
ジョシュ

さらに、DragonFlyBSDのHAMMERファイルシステムは重複排除をサポートしています。
ハハム

14
ZFS dedupは誰の友達でもありません。ZFSが1Tbの使用可能なディスク容量あたり1GbのRAMを推奨している場合、1Gbの使用可能なディスク容量あたり32Gb未満のRAMでdedupを使用しようとすると、非常に簡単です。つまり、1Tbミラーの場合、32GbのRAMがないと、遅かれ早かれメモリ爆弾の状態に遭遇し、RAMの不足によりマシンが停止する可能性があります。そこに行って、それをして、まだPTSDから回復しています。
キラーミスト14

4
オンライン重複排除で過度のRAM要件を回避する(つまり、書き込みごとに確認する)にbtrfsは、バッチ重複排除またはオフライン重複排除を使用します(有用/必要と思われるときに実行します) btrfs.wiki.kernel.org/index.php/Deduplication
Marcel Waldvogel

3
7年後の更新:私は最終的にZFSに移行し、重複排除を試みました-RAMの要件は確かに非常に高いことがわかりました。ZFSスナップショットを巧妙に使用することで、最終的に使用するソリューションが提供されました。(1人のユーザーの音楽をコピーし、スナップショットとクローンを作成し、2番目のユーザーの音楽をクローンにコピーして、rsync --inplace変更されたブロックのみを保存します)
ジョシュ


5

重複するファイルを見つけるには、duffを使用できます。

Duffは、特定のファイルセット内の重複をすばやく見つけるためのUnixコマンドラインユーティリティです。

単に実行する:

duff -r target-folder

それらのファイルへのハードリンクを自動的に作成するには、bashまたは他のスクリプト言語でduffの出力を解析する必要があります。



5
aptitude show hardlink

説明:同じファイルの複数のコピーをハードリンクするハードリンクは、同じファイルの複数のコピーを検出し、それらをハードリンクに置き換えるツールです。

このアイデアはhttp://code.google.com/p/hardlinkpy/から引用されていますが、コードはゼロから書かれており、MITライセンスの下でライセンスされています。ホームページ:http : //jak-linux.org/projects/hardlink/


ここで言及した唯一のプログラムは、Gentooでマスクを解除せずに、ハードリンクをサポートして利用可能です、ありがとう!
ジョリットシッパーズ

4

ここで言及したLinux用のハードリンクツールの多くを使用しました。私もUbuntuでext4 fsに固執しており、ハード/ソフトリンクにcp -lおよび-sを使用しています。しかし最近、cpのマニュアルページに軽量コピーがあり、一方が変更されるまで冗長ディスクスペースを節約することを意味します。

   --reflink[=WHEN]
          control clone/CoW copies. See below

       When  --reflink[=always]  is specified, perform a lightweight copy, where the 
data blocks are copied only when modified.  If this is not possible the
       copy fails, or if --reflink=auto is specified, fall back to a standard copy.

私は私が私の更新になると思いcp、常に含まれるようにエイリアスを--reflink=auto今すぐパラメータを
マルコス

1
ext4は本当にサポートしてい--reflinkますか?

7
これは、btrfsおよびOCFS2でサポートされています。コピーオンライトファイルシステムでのみ可能ですが、ext4ではできません。btrfsは本当に形を整えています。reflinkとスナップショットのために使用するのが大好きで、ファイルの大きなツリーで大量の操作を行うことを怖がらせません。
12

3

最初にファイル名をチェックすることで速度が上がると思います。2つのファイルに同じファイル名がない場合、多くの場合、それらが重複しているとは思わないでしょう。最も速い方法は、順番に比較することだと思われます:

  • ファイル名
  • サイズ
  • md5チェックサム
  • バイト内容

これを行う方法はありますか?見てdufffdupesrmlintfslint、など

以下の方法がcommandlinefu.comでトップ投票されました:重複ファイルを検索(サイズに基づいて、次にMD5ハッシュ)

ファイル名の比較を最初のステップとして、サイズを2番目のステップとして追加できますか?

find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | \
  xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | \
  sort | uniq -w32 --all-repeated=separate

3
私は使用しましたdufffdupesそしてrmlint、読者にこれらの3番目を見るよう強く勧めます。優れたオプションセット(およびドキュメント)があります。これにより、他のツールで使用する必要のあった後処理の多くを回避することができました。
dubiousjim

3
私の練習では、ファイル名は最も信頼性の低い要素であり、重複排除の取り組みから完全に削除しました。どのように多くinstall.shのファイルがアクティブなシステム上で見つけることができますか?ファイルを保存して名前が衝突した回数はカウントできませんが、その場で名前を変更して保存します。裏返し:さまざまなソースから、さまざまな日に何かをダウンロードした回数はわかりませんが、それらは同じ名前の異なるファイルであることがわかります。(タイムスタンプの信頼性も失われます。)1:サイズ、2:ダイジェスト、3:バイトコンテンツ。
ジプシースペルウィーバー

@GypsySpellweaver:(1)個人的なユースケースに依存します、あなたは同意しませんか?私の場合、同じ名前と内容のファイルが異なる復元フォルダーに存在する複数のバックアップから複数の復元があります。(2)あなたのコメントは、ファイル名の比較のみを前提としているようです。他のチェックを削除することを提案していませんでした。
ジョニーなぜ

2

私はPerlのファンではないので、ここにbashバージョンがあります。

#!/bin/bash

DIR="/path/to/big/files"

find $DIR -type f -exec md5sum {} \; | sort > /tmp/sums-sorted.txt

OLDSUM=""
IFS=$'\n'
for i in `cat /tmp/sums-sorted.txt`; do
 NEWSUM=`echo "$i" | sed 's/ .*//'`
 NEWFILE=`echo "$i" | sed 's/^[^ ]* *//'`
 if [ "$OLDSUM" == "$NEWSUM" ]; then
  echo ln -f "$OLDFILE" "$NEWFILE"
 else
  OLDSUM="$NEWSUM"
  OLDFILE="$NEWFILE"
 fi
done

これにより、同じチェックサムを持つすべてのファイル(大きい、小さい、または既にハードリンクであるかどうか)が検出され、それらが一緒にハードリンクされます。

これは、追加の検索フラグ(サイズなど)とファイルキャッシュを使用して繰り返し実行するように大幅に最適化できます(そのため、毎回チェックサムをやり直す必要はありません)。よりスマートで長いバージョンに興味がある人は、投稿できます。

注:前述したように、ハードリンクは、ファイルを変更する必要がないか、ファイルシステム間で移動する必要がない限り機能します。


スクリプトを変更して、ハードリンクする代わりに、重複ファイルを削除し、CSVファイルに削除されたファイル->裏打ちされたファイルを追加します。。???
MR.GEWA

承知しました。ハードリンク行:echo ln -f "$ OLDFILE" "$ NEWFILE"重複ファイルをハードリンクに置き換えるだけなので、代わりに$ NEWFILEを使用して変更できます。
セレン

そして、次の行では、何らかの方法でテキストファイルに$ OLDFILE-> NEWFILEを書き込みます。???
MR.GEWA

ああ、そう。はい、rmの後に次のような行を追加します。echo "$ NEWFILE" >> /var/log/deleted_duplicate_files.log
seren

2
車輪を再発明しないでください。のようなより成熟したソリューションがあり、rdfindネイティブの速度で動作し、インストールを必要とするbrew install rdfindapt-get install rdfind、インストールするだけです。
オリゴフレン

1

あなたが話しているのと似たようなことをするPerlスクリプトを作成しました。

http://pastebin.com/U7mFHZU7

基本的には、ディレクトリを走査し、その中のファイルのSHA1sumを計算し、ハッシュして一致をリンクします。これは、多くの場合に便利です。


2
私はこれをすぐに試してみたいと思います... CPANにアップロードしてみませんか... App ::
relink

2
@xenoterracide:すでに存在する類似のより成熟したソリューションがすべてあるためです。他の回答、特にrdfindを参照してください。
オリゴフレン

1
@oligofrenより良い解決策が存在することは疑いません。TMTOWTDI私は推測する。
amphetamachine

1

あなたがMacのハードリンクまたは任意のUNIXベースのシステムで重複を交換したい場合は、SmartDupe試すことができますhttp://sourceforge.net/projects/smartdupe/は それを開発しています


3
それがいかに「スマート」であるかを拡張できますか?
ステファンギメネス

1
2つの異なるディレクトリのファイルを比較するにはどうすればよいですか?
ブルカルド

1

applicatios FSLint(http://www.pixelbeat.org/fslint/)は、(コンテンツごとに)任意のフォルダー内のすべての等しいファイルを検索し、ハードリンクを作成できます。試してみる!

ホルヘ・サンパイオ


1TBのほぼ満杯のext3ハードディスクのスキャンを停止し、システム全体をクロールします。「検索」の14時間後に中止
アンスマンチャクラボルティ

1

jdupes コメントで言及されていますが、ほとんどのディストリビューションでおそらく利用可能であり、非常に高速に実行されるため、独自の答えに値します(約1分で98%フル158GBパーティション(SSDドライブ)の2.7GBを解放しました):

jdupes -rL /foo/bar

0

ハードリンクを行う場合は、そのファイルの権利に注意してください。通知、所有者、グループ、モード、拡張属性、時間、およびACL(これを使用する場合)はINODEに保存されます。これはディレクトリ構造に保存されているため、ファイル名のみが異なり、他のポイントはINODEプロパティを指します。この原因は、同じiノードにリンクされているすべてのファイル名が同じアクセス権を持っていることです。すべてのユーザーが他のユーザーにファイルを損傷する可能性があるため、そのファイルの変更を防止する必要があります。それは単純だ。それは十分です、すべてのユーザーが同じ名前で他のファイルを置きます。その後、iノード番号が保存され、すべてのハードリンクされた名前の元のファイルの内容が破棄(置換)されます。

より良い方法は、ファイルシステム層での重複排除です。BTRFS(前回非常に人気があった)、OCFSなどを使用できます。次のページをご覧ください:https : //en.wikipedia.org/wiki/Comparison_of_file_systems 、特にテーブルの機能と列データの重複排除。クリックして並べ替えることができます:)

特にZFSファイルシステムを見てください。これはFUSEとして利用できますが、この方法では非常に遅いです。ネイティブサポートが必要な場合は、http://zfsonlinux.org/ページをご覧ください。次に、カーネルにパッチを適用し、次に管理用のzfsツールをインストールする必要があります。なぜLinuxがドライバーとしてサポートしていないのか、他の多くのオペレーティングシステム/カーネルの方法であることがわかりません。

ファイルシステムは、重複排除ファイルまたはブロックの2つの方法で重複排除をサポートします。ZFSはブロックをサポートしています。つまり、同じファイル内で繰り返される同じコンテンツを重複排除できます。他の方法は、データが重複排除される時間です。これは、オンライン(zfs)またはオフライン(btrfs)のいずれかです。

重複排除はRAMを消費することに注意してください。これが、FUSEでマウントされたZFSボリュームにファイルを書き込むと、パフォーマンスが劇的に低下する理由です。これはドキュメントに記載されています。ただし、ボリュームの重複排除をオンラインで設定できます。データの重複排除が必要な場合は、単に重複排除をオンに設定し、一部のファイルを一時ファイルに書き換えて、最終的に置き換えます。この後、重複排除をオフにして、完全なパフォーマンスを復元できます。もちろん、任意のキャッシュディスクをストレージに追加できます。これには、非常に高速な回転ディスクまたはSSDディスクを使用できます。もちろん、これは非常に小さなディスクでもかまいません。実際の作業では、これはRAMの代替です:)

Linuxでは、ファイルシステムの管理、スナップショットの作成などを行うとすべてが正常に機能するわけではないため、ZFSに注意する必要がありますが、設定を行って変更しない場合はすべて正常に動作します。また、Linuxをopensolarisに変更する必要があります。ZFSをネイティブにサポートします:) ZFSの非常に優れている点は、LVMと同様にファイルシステムとボリュームマネージャーの両方として機能することです。ZFSを使用する場合は必要ありません。詳細については、ドキュメントを参照してください。

ZFSとBTRFSの違いに注意してください。ZFSはより古く、より成熟しており、残念なことにSolarisとOpenSolaris(残念なことにoracleによって絞殺された)の下でのみです。BTRFSはより若いですが、前回は非常によくサポートされています。新鮮なカーネルをお勧めします。ZFSにはオンライン重複排除機能があり、すべてがオンラインで計算されるため、書き込み速度が低下します。BTRFSはオフライン重複排除をサポートしています。その後、これによりパフォーマンスは節約されますが、ホストが何もすることがない場合は、重複排除のためのツールを定期的に実行します。また、BTRFSはLinuxでネイティブに作成されます。たぶんこれはあなたにとってより良いFSです:)


1
オフライン(またはバッチ)重複排除アプローチbtrfsが好きです。オプション(オプションを含むcp --reflink)の優れた議論はこちら:btrfs.wiki.kernel.org/index.php/Deduplication
マルセルヴァルトフォーゲル

ZFSは、SolarisまたはOpenSolarisのみではありません。FreeBSDでネイティブにサポートされています。また、Linux上のZFS デバイスドライバーベースです。FUSE上のZFSは別のものです。
KJ

0

ハードリンクは最良のアイデアではないかもしれません。1人のユーザーがファイルを変更すると、両方に影響します。ただし、ハードリンクを削除しても、両方のファイルは削除されません。さらに、ハードリンクが同じファイルの複数のコピーと同じ量のスペース(OSではなく、ハードディスク上)を占有するかどうかは完全にはわかりません。Windows(Link Shell Extensionを使用)によると、そうです。確かに、それはUnixではなくWindowsです...

私の解決策は、隠しフォルダーに「共通」ファイルを作成し、実際の重複をシンボリックリンクで置き換えることです...その後、シンボリックリンクはメタデータまたは2つの「ファイル」のみを記録する代替ファイルストリームに埋め込まれます1人がファイル名を変更したり、カスタムアルバムアートなどを追加したい場合など、互いに異なります。同じゲームやソフトウェアの複数のバージョンをインストールし、わずかな違いでも個別にテストするなど、データベースアプリケーション以外でも役立つ場合があります。


0

最も簡単な方法は、特別なプログラムdupeGuruを使用することです

dupeGuru Preferencesスクリーンショット

ドキュメントが語ります

削除オプション

これらのオプションは、重複削除の実行方法に影響します。ほとんどの場合、それらを有効にする必要はありません。

削除されたファイルをリンク:

削除されたファイルは、参照ファイルへのリンクに置き換えられます。シンボリックリンクまたはハードリンクのいずれかで置き換えることができます。...シンボリックリンクは、ファイルのパスへのショートカットです。元のファイルが削除または移動されると、リンクが壊れます。ハードリンクは、ファイル自体へのリンクです。そのリンクは、「実際の」ファイルと同じくらい優れています。ファイルへのすべてのハードリンクが削除された場合にのみ、ファイル自体が削除されます。

OSXおよびLinuxでは、この機能は完全にサポートされていますが、Windowsでは、少し複雑です。Windows XPはサポートしていませんが、Vista以降ではサポートしています。ただし、機能を機能させるには、dupeGuruを管理者権限で実行する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.