rsyncディレクトリを比較しますか?


63

rsyncで2つのディレクトリを比較し、違いのみを出力することは可能ですか?ドライランオプションがありますが、詳細度を特定のレベルに上げると、比較されたすべてのファイルが表示されます。

ls -alRそしてdiffすべての行を異ならせるソースのハードリンクがあるので、ここにはオプションではありません。(もちろん、perlでこの列を削除できます。)


回答:


46

双方向のような何かを実行する必要があり rsync -avun --deleteます。

しかし、実際に何を達成しようとしていますか?

更新

rsync -avun --delete $TARGET $SOURCE |grep "^deleting " ターゲットディレクトリに存在しないファイルのリストが表示されます。

各ラインのプリントなぜなら"grepのDELET":DELET INGの..FILE ..

rsync -avun $SOURCE $TARGET 「異なる」ファイル(新しいファイルを含む)のリストが表示されます。


49

Nilsの答えに追加するために(Google経由でこれに遭遇した人のために)、デフォルトrsyncではファイルサイズと変更時間のみを比較して違いがあるかどうかを判断します。(それらが異なる場合、それはより多くを行いますが、それらが同じである場合、そこで停止します。)

実際のファイルの内容を比較したい場合、同じサイズで最終更新時刻が同じファイルであっても、チェックサムを使用してファイルを比較-cするようrsyncにフラグを追加します。

rsync -avnc $SOURCE $TARGET

(この-uオプションは、rsyncに$TARGETonよりも新しいファイルを無視するように指示します。これは$SOURCE、コンテンツを比較する場合はおそらく必要ありません。)


6
データが同じであることだけを気にする場合は、必要に応じて追加--no-group --no-owner --no-perms --no-timesまたはこれらの組み合わせを追加できます。
フルンゴ

1
@flungo、またはの-a代わりに暗黙的に示されたオプションのサブセットを使用します-a。たとえばrsync -rlDcnv --delete $SOURCE $TARGET
maxschlepzig

追加してください--deleteだけで既存のファイル一覧表示する$TARGET
トム・ヘイル

25

あまり知らない人のためにrsync

rsync -rvnc --delete ${SOURCE}/ ${DEST}
  • -n:最も重要なビット- 何も変更しないでください。
  • -rc:内容のみを比較します(そうでない場合は使用します-ac)。
  • -v :ファイルをリストします)
  • --delete :一方向の違いではなく、対称的な違いを探してください。
  • 最後に、/「ディレクトリ内を見て、その内容を宛先と比較する」ことを意味します。

通常のrsync出力を印刷しますが、

  • すべての「新しい」ファイルの行に1つの<filename>${SOURCE}
  • およびの各「新規」ファイルごとに1行の「削除<filename>」${DEST}

  • また、シンボリックリンクの「通常でないファイル<filename>をスキップする」など、いくつかの警告を出力する場合があります。

PS。私はそれがひどいPSであることを知っていますが、実際に急いで追加されました。それにもかかわらず、私はこれが役に立つと思うかもしれません。


PPS。あるいは、次のこともできます。

find $SOURCE -type f -exec md5sum {} \; | tee source.md5
find $DEST   -type f -exec md5sum {} \; | tee dest.md5

ファイル名に改行が含まれていない場合は、両方の*.md5ファイルとdiffそれらを並べ替えることができます。(ただし、これはファイルに対してのみ機能します。つまり、両側の空のディレクトリは検出されません。)


15

驚くべきことに、6年以内に答えが-iオプションを使用しないか、素晴らしい出力を与えるので、ここに行きます:

TLDR-コマンドを表示するだけ

rsync -rin --ignore-existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^[^ ]* /L             /'
rsync -rin --ignore-existing "$RIGHT_DIR"/ "$LEFT_DIR"/|sed -e 's/^[^ ]* /R             /'
rsync -rin --existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^/X /'

出力を理解する

出力の例を次に示します。

L             file-only-in-Left-dir
R             file-only-in-right-dir
X >f.st...... file-with-dif-size-and-time
X .f...p..... file-with-dif-perms

すべての行の最初の文字に注意してください。

  • L/ Rは、ファイル/ディレクトリがLeftまたはRightディレクトリにのみ表示されることを意味します。
  • X(次の11の文字はあなたより多くの情報を与え、その場合には、ファイルが両側に表示されますが、同じではないことを意味しstそしてpの違い描いS、IZE トン IMEとのp -詳細は試すそれぞれermissionsをman rsyncしての検索が--itemize-changes) 。

使用したい追加オプション

ファイルの所有者/グループ/権限も比較したい場合は、それぞれオプション-o/ -g/を追加します-p。最後に、rsyncがデフォルトで同じ名前、時間、サイズを持っている場合、2つのファイルを同じと見なすことに注意してください。これは非常に高速で、ほとんどの場合十分です。ただし、100%にしたい場合-cは、同じ名前、時間、サイズのファイルの内容も比較してください。

TLDR-呼び出すスクリプトを教えてください

ここにあります。このように呼んでください

diff-dirs Left_Dir Right_Dir [options]

上記の「使用する可能性のある追加オプション」セクションで説明したすべてのオプションもここに適用されます。

#!/bin/bash
# Compare two directories using rsync and print the differences
# CAUTION: options MUST appear after the directories
#
# SYNTAX
#---------
# diff-dirs Left_Dir Right_Dir [options]
#
# EXAMPLE OF OUTPUT
#------------------
# L             file-only-in-Left-dir
# R             file-only-in-right-dir
# X >f.st...... file-with-dif-size-and-time
# X .f...p..... file-with-dif-perms
#
# L / R mean that the file/dir appears only at the `L`eft or `R`ight dir. 
#
# X     means that a file appears on both sides but is not the same (in which
#       case the next 11 characters give you more info. In most cases knowing
#       that s,t,T and p depict differences in Size, Time and Permissions 
#       is enough but `man rsync` has more info
#       (look at the --itemize-changes option)
#
# OPTIONS
#---------
# All options are passed to rsync. Here are the most useful for the purpose
# of directory comparisons:
#
# -c will force comparison of file contents (otherwise only
#    time & size is compared which is much faster)
#
# -p/-o/-g will force comparison of permissions/owner/group

if [[ -z $2 ]] ; then
    echo "USAGE: $0 dir1 dir2 [optional rsync arguments]"
    exit 1
fi

set -e

LEFT_DIR=$1; shift
RIGHT_DIR=$1; shift
OPTIONS="$*"

# Files that don't exist in Right_Dir
rsync $OPTIONS -rin --ignore-existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^[^ ]* /L             /'
# Files that don't exist in Left_Dir
rsync $OPTIONS -rin --ignore-existing "$RIGHT_DIR"/ "$LEFT_DIR"/|sed -e 's/^[^ ]* /R             /'
# Files that exist in both dirs but have differences
rsync $OPTIONS -rin --existing "$LEFT_DIR"/ "$RIGHT_DIR"/|sed -e 's/^/X /'

どのように機能しますか?

次のようにrsyncを呼び出しています。

rsync -rin ...

-i--itemize-changes)を使用して、2つのディレクトリ間の違いに関する情報を含むすべてのファイルに対して1行の出力を印刷するようにrsyncに指示します。-nrsyncの通常の動作を抑制する必要があります(ファイルをコピー/削除して2つのディレクトリを同期しようとします)。また-r、すべてのファイル/サブディレクトリに対して再帰的に作業する必要があります。

rsyncを3回呼び出します。

最初の呼び出し:Dir_Bに存在しないファイルを印刷します。--ignore-existing両側に存在するファイルを無視するために使用する必要があります。

rsync -rin --ignore-existing $DIR_A/ $DIR_B/

2回目の呼び出し:前とまったく同じですが、DIR_A / DIR_Bの順序を入れ替えます。

3番目の呼び出し:最後に--existing、両方のディレクトリに表示されるファイルのみをチェックします。

rsync -rin --existing $DIR_A/ $DIR_B/

他の人については知りませんが、私はあなたのスクリプトを使用しています。すごい仕事!ありがとう
Marinaio

7

あなたの質問から、lsでdiffを使用したくないことを理解していますが、ディレクトリでdiffを再帰的に使用することもできます:

diff -rq DIR1 DIR2

2

これを機能させるのに数回試行しました。ジョージが説明したよう$TARGETに、Nilsの答えでは、末尾が末尾/になっている必要があります。

これは明示的に末尾を追加するバージョンです/

rsync -avun --delete ${TARGET}/ ${SOURCE}  | sed -ne 's/^deleting *//p'

これにより、${SOURCE}ディレクトリの下に存在するがディレクトリの下には存在しないファイルのリストが表示されます${TARGET}

sedここでdeletingは、出力行から先頭を削除し、それらの行のみを印刷するために使用します。

私のユースケースではファイルの内容の比較が非常に遅くなるため、このrsyncオプションを使用しません-c。これらの場合、ファイルのサイズと変更時間のみの比較でも十分だと思われます。私のコンピューターがクロックスキューの問題に苦しんでいるのか、何かが悪意を持ってタイムスタンプを変更したのではないかと疑う理由はありません。また、の結果は-cファイルを削除する決定を変更することはできず、ファイルを更新または保持する決定のみを変更します。

また-u-a(ではなく-r)andを使用します。これにより、後でコマンドラインを再利用し、選択したディレクトリとファイルを${SOURCE}to からにコピーするように変更できます${TARGET}

rsync -avu ${SOURCE}/{dirA,dirB,fileX} ${TARGET}   # copy some files

0

これを行う別のアイデアがあります:

rsync -rn --out-format=FILEDETAIL::%n  $TARGET $SOURCE  | grep "^FILEDETAIL"

「FILEDETAIL ::」をコマンドの出力と一致させることができます。また、文字列「FILEDETAIL ::」を変更できます。「%n」はファイル名です。

-rこれは、ディレクトリを再帰的にコピーするようにrsyncに指示します。

-nこれにより、rsyncは変更を行わない試用を実行します。

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