2つのディレクトリを同期したい。最初のディレクトリにはCRLF
と通常の行末があり、2番目のディレクトリにもCRLF
と通常の行末のファイルがあります。
問題は、このコードを実行すると、次のようになります。
rsync -azr --exclude=images --dry-run --delete --checksum --out-format="/%f" /dir1 /dir2
同一であるがエンコーディングが異なる多くのファイルが同期されることを示しています。異なるコンテンツファイルのみを同期したいと思います。
diff
を使用すると、次のことが可能になります。
diff --strip-trailing-cr file1 file2
しかし、Rsyncではこのようなものは見つかりませんでした。異なるコンテンツのファイルのみを同期するにはどうすればよいですか?
rsync
の行末を無視するオプションはありませんご存知のように、rsync
は、 行末 が異なるファイルを異なるものと見なします。ファイルは視覚的/意味的に同じであるため、これは状況に不便です。
rsync
は、ブロックのチェックサムに基づいて、ファイルで何を同期するかを決定します。 これに関する概要 があります:
(T)ファイルの古いバージョンは、たとえば次のブロックに分割されます。 1024バイトまたは2048バイトで、ブロックごとにチェックサムが計算されます。
次に、新しいファイルで、古いバージョンのチェックサムと一致するチェックサムを持つブロックのバイトが検索されます。このプロセスを示す図を次に示します。
新しいバージョンのファイルでこれらの操作を繰り返すと、ファイルのバイトごとに繰り返されます。この反復中に、ファイルには2つのタイプのデータがあります。
- 古いファイルのブロックと一致するデータのブロック。
- 一致するブロックの一部ではないバイトのシーケンス。
From RSync-Detecting File Differences byJakob Jenkov。
興味がある場合は、次のセクションは 使用されるチェックサム です。ただし、チェックサムの要点は、バイト)で機能し、ファイルのファイルのバイト数が行末であるため、バイトが異なることです。そのため、rsync
は、それらが異なることを正しく検出しているため、転送しています。それら。
これを行うための最良の言い方は、コメントで Kamil が示唆しているように、すべてのファイルの行末が一貫していること、またはsanitizeそれら)であることを確認することです。
これをどのように行うかはあなた次第です。ファイルが生成、編集、または更新されたときに変更を加えることを決定する場合があります。または、転送前の手順として実行することもできます。
サニタイズを行う場合は、カミルがさらに警告するように、必ず盲目的に適用しないでください)。
すべてのファイルで盲目的に変換ツールを使用するべきではありません。ツールがファイルがテキストであるかバイナリであるかを推測しようとしても、それはヒューリスティックにすぎません。 CRLFはバイナリファイル内に表示される場合があります。テキストのように見えるブロックも表示される場合があります。 いくつかのバイトを削除してバイナリファイルを変更すると、おそらくそれが破損します。
(私の強調)
たとえば、2つのディレクトリに、サニタイズが必要なテキストファイルであることがわかっているファイルがある場合は、サニタイズ手順をそのサブセットにのみ適用します。
完全なソリューションは、この回答の範囲を超えています。 このSO QA には、dos2unix
、tr
、sed
、awk
、Perl
などのいくつかの提案があります。
例えば:
tr
を使用して、DOSからUnixに変換できます。ただし、これを安全に行うことができるのは、CRがCRLFバイトペアの最初のバイトとしてのみファイルに表示される場合のみです。これは通常の場合です。次に、以下を使用します。tr -d '\015' <DOS-file >UNIX-file
ただし、これを非常に頻繁に(大まかに言えば、複数回)実行する必要がある場合は、変換プログラム(
dos2unix
とunix2dos
、またはおそらくdtou
など)をインストールする方がはるかに賢明です。およびutod
)そしてそれらを使用します。
ジョナサンレフラーの答え から。
ただし、これらのツールのいずれかを使用する場合は、上記の警告に注意してください。