web-dev-qa-db-ja.com

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

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

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

146
Josh

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

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

42
fschmitt

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

コンパイルされているので、ほとんどのスクリプトソリューションよりも高速です。15上のtime GiB 2009からの私のMac Mini上の2600ファイルを含むフォルダーはこれを返します

9.99s user 3.61s system 66% cpu 20.543 total

(md5を使用)。

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

98
d-b

fdupesツールを使用します。

fdupes -r /path/to/folderは、ディレクトリ内の重複のリストを提供します(-rを指定すると再帰的になります)。出力は次のようになります。


ファイル名1
ファイル名2

ファイル名3
ファイル名4
ファイル名5


filename1とfilename2は同じで、filename3、filename4、filename5も同じです。

51
tante

http://jak-linux.org/projects/hardlink/hardlinkを使用します

24
waltinator

これは「fslint」が提供する機能の1つです- http://en.flossmanuals.net/FSlint/Introduction

[マージ]ボタンをクリックします。

Screenshot

18
LJ Wobker

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

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

14
Wei-Yin

最近のLinuxには、最近 https://github.com/g2p/bedup があり、btrfsファイルシステムで重複排除されますが、1)スキャンのオーバーヘッドがそれほど大きくなく、2)ファイルは簡単に分岐できますその後再び。

7
Matthew Bloch
aptitude show hardlink

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

アイデアは http://code.google.com/p/hardlinkpy/ からとられていますが、コードはゼロから作成され、MITライセンス。ホームページ: http://jak-linux.org/projects/hardlink/

6
Julien Palard

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

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

単に実行する:

duff -r target-folder

これらのファイルへのハードリンクを自動的に作成するには、duffの出力をbashまたは他のスクリプト言語。

6
Stefan

ここで説明したLinux用のハードリンクツールの多くを使用しました。私もUbuntuでext4 fsにこだわっており、cp -l-sハード/ソフトリンク用。しかし、最近cpのmanページにあるlightweight copyに気づきました。これは冗長ディスクスペースuntil片側が変更されます:

   --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.
4
Marcos

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

jdupes -rL /foo/bar

最初にファイル名を確認すると、処理が速くなるように思えます。 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
4
johny why

私は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

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

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

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

3
seren

Macまたは任意のUNIXベースのシステムでハードリンクによって重複を置き換えたい場合は、SmartDupeを試すことができます http://sourceforge.net/projects/smartdupe/ 開発中

1
islam

私はあなたが話していることに似た何かをするPerlスクリプトを作りました:

http://Pastebin.com/U7mFHZU7

基本的に、それはディレクトリを横断し、その中のファイルのSHA1sumを計算し、それをハッシュし、一致をリンクします。多くの場面で重宝します。

1
amphetamachine

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

ホルヘ・サンパイオ

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

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

0
Amaroq Starwind

ハードリンクを行う場合は、そのファイルの権利に注意してください。通知、所有者、グループ、モード、拡張属性、時間、および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あなたのために:)

0
Znik

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

dupeGuru Preferences Screenshot

documentation が言うように

削除オプション

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

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

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

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