rsnapshot
同じディレクトリ構造の複数のスナップショットを含み、同じファイルがすべてハードリンクに置き換えられたディレクトリツリーが作成されました。
これらのハードリンクの重複エントリをすべて削除し、各ファイルのコピーを1つだけ保持したいと思います。これにより、後で同じファイルに2回触れることなく、すべてのファイルをソートされたアーカイブに移動できます。
これを行うためのツールはありますか?
これまで、重複項目を見つけることができるツールだけが見つかりました。作るこれに代わるハードリンク...
すべてのファイルとそのinode番号をリストし、重複排除と削除を直接実装できると思いますが、ここではホイールを再発明したくありません。
答え1
最後に、これを手動で行うことはそれほど難しくありません。スティーブンそしてジェノイドのようなヒントといくつかの事前経験find
。
FreeBSDのGNU以外のツールと連携するには、いくつかのコマンドを調整する必要がありました。 GNUにはそれを置き換えるオプションがfind
ありますが、FreeBSDはそうではありません。-printf
-exec stat
find
# create a list of "<inode number> <tab> <full file path>"
find rsnapshots -type f -links +1 -exec stat -f '%i%t%R' {} + > inodes.txt
# sort the list by inode number (to have consecutive blocks of duplicate files)
sort -n inodes.txt > inodes.sorted.txt
# remove the first file from each block (we want to keep one link per inode)
awk -F'\t' 'BEGIN {lastinode = 0} {inode = 0+$1; if (inode == lastinode) {print $2}; lastinode = inode}' inodes.sorted.txt > inodes.to-delete.txt
# delete duplicates (watch out for special characters in the filename, and possibly adjust the read command and double quotes accordingly)
cat inodes.to-delete.txt | while read line; do rm -f "$line"; done
答え2
複数のリンクを持つ索引ノードを見つけるには、次のようにします。
find . -exec stat -c '%i' {} \; | sort -n | uniq -d
その後、そのリストを繰り返すことができます。
find -inum {inode_number}
このinodeを共有するファイルをリストします。どちらを削除するかはあなた次第です。
答え3
すべてのファイルが単一のディレクトリ階層のハードリンクのみを持っていることがわかっている場合は、単に次のことができます。
find inputdir -type f -links +1 -exec rm {} \;
その理由は、rm {} \;
ファイルをすぐに削除するとstat()
1つ以上の数が返されるためです。したがって、同じ inode の他の部分のハードリンク数は 1 ずつ減らされ、そのファイルが唯一のコピーである場合、最後のファイルでrm
find 実行時にそのファイルに対しては find は実行されませんstat()
。
ファイルにinputdir
このコマンド以外のハードリンクコピーがある場合は注意してください。すべてのコピーが削除されます。階層内でinputdir
!