きまブログ

5/31 はてなダイアリーから移行しました。


【備忘録】ディレクトリを比較して差分ファイルだけディレクトリ構造ごと、別ディレクトリへコピーする。

とある都合で、次のような差分ファイル群(?)を作る必要に迫られて、
ちょっと調べても、検索キーワードが良くないのか、
いい方法が見つからなかったので。。
探すより、とりあえずやってみよう。
ということで,次の手順で所望のことはできたので備忘録です。

ミッション
  1. 2つのディレクトリを比較して、編集/追加したファイルのみ、ディレクトリ構造ごと、別ディレクトリへコピーする。差分だけ別に抽出する。
条件
  1. OS : Linux(動作確認はCentOS6)
  2. ディレクトリdirA配下にあるファイル群をdirAごとコピーしてdirBとする。($ cp -arp dirA dirB)
  3. dirB配下のファイルを編集したり、ファイルを追加したりする。

 ※ とりあえず、削除はしない。。

  1. バージョン管理ツールなどは使ってないみたいw
  2. 元のディレクトリにハード・シンボリックリンクがないこと。。

とりあえず思いついたやり方。。

大切なデータなので,実行するときは,
動作を確認してから実施して下さい。
データがなくなっても,責任取れませんので。。あしからず。。

rsync --link-destオプションでバックアップをする。

$ rsync -avn --link-dest=../dirA ./dirB/ ./dirC/
として,まずdirBをdirCへバックアップする。(dirB=dirC)
オプションにnをつけるとdry-runモードで、
実際には実行せずに、転送するファイルを確認するができます。
実行する時は、オプションからnを外す。

これで、dirBの内容がdirCへバックアップされる。
この時、dirAとdirBを比較し、dirAとdirBで同じファイルはdirAのハードリンクとして生成される。
※ この段階で、rsyncに、ハードリンクを作成しないオプションがあればそれでいいのだけれど。。見つけられなかった。。

find -linksオプションで、ハードリンクが張られているファイルを削除する。

バックアップ先のdirCで,ハードリンクを削除します。

$ cd dirC
$ find . ! -links 1 -type f -delete

dirC配下でlink数が1でないファイルは削除される。
dirAとdirBで同じファイルはハードリンクになるのでリンク数が2以上になっているはず。。
これで,dirCには,更新したファイルしか残ってない。

残った空のディレクトリを削除する。

$ find . -type d -empty -delete

空のディレクトリを削除します。

φ(..)メモメモ

  1. 知識不足のための再発明かもしれない。。きっとそう。
  2. rsyncはオプションが膨大。探せばコマンド一発で実現できるヤツがあるかも。。
  3. rsyncの-nオプションは素晴らしい。
  4. findコマンドは-deleteオプションでマッチしたモノを削除できる。
  5. Windowsでは,そういうツールがあるみたい。。