これを参照してください公開チェックサムに基づく重複ファイルの検索と削除、コピー操作の実行方法を変更してから、ターゲットファイルに対してファイル整合性チェックを実行したいと思います。
SOURCE = /path/to/Source
DEST = /path/to/Destination
# filecksums containing the md5 of the copied files
declare -A filecksums
for file in "$@"
do
[[ -f "$file" ]] || continue
# Generate the checksum
cksum=$(cksum <"$file" | tr ' ' _)
# Can an exact duplicate be found in the destination directory?
if [[ -n "${filecksums[$cksum]}" ]] && [[ "${filecksums[$cksum]}" != "$file" ]]
then
rm -f "$file"
else
echo " '$file' is not in '$DEST'" >&2
fi
done
md5チェックサム比較結果を使用しrm -f
、チェックサムが同じ場合にのみソースファイルを許可したいと思います。違いがある場合は、結果をエコーしてエスケープしたいと思います。rsync
別のオプションかもしれませんが、ローカル間のファイル転送に対して強制的にチェックサム比較を実行すると問題が発生する可能性があると思います。
修正する
@Lucasの答えに基づいてrsyncの使用を調べました。ファイルを一括転送するのではなく確認しmv /data1/* /data2/
、完了したジョブを報告し、確認後に削除する方法でファイルをより確実に転送するオプションがあるようです。コミュニティメンバーが指摘したように、これは定義を絞り込むことができます。
答え1
ファイルに興味があり、めまいをしたくない場合は、最初にこのようなものを実装するのが難しいかもしれません。したがって、bashで完全なスクリプトを書くことにはいくつかの選択肢があります。これらのやや複雑なコマンドラインがあなたの場合に役立つかもしれません。
あなたの質問に不確実性があります。比較したいですか?各ソースファイルには以下が含まれます。すべてファイルはターゲットにありますか、それとも「一致する」ファイル名を持つファイルのみが含まれていますか? (これは/path/to/src/a
AND比較ですが、ANDなどではありません/path/to/dest/a
。)/path/to/src/b
/path/to/dest/b
/path/to/src/a
/path/to/dest/b
私はあなたがパスが一致するファイルだけを比較したいと思います!
最初の考え:diff
古い方が良いdiff
ディレクトリは再帰的に比較できます。-q
オプションを使用して、どのファイルが異なるか、どのファイルが異なるかを確認することもできます。どのように彼らは違う。
diff -r -q /path/to/source /path/to/dest
欠点
- これを行うには長い時間はハードドライブのサイズによって異なります。
- 古いファイルは削除されません。
- 出力を解析するのは簡単ではありません。
利点
- ファイルは削除されません:)
したがって、関心のあるファイルに違いがないことを手動/視覚的に確認した後rm -rf /path/to/source
。
2番目の考え:(rsync
編集:おそらく今はこれが最高でしょう)
rsync
すべてのレプリケーションコマンドラインツールのマスターです(私の考えでは;)。あなたの質問についてのコメントで述べたように、1つのオプションがありますが、--checksum
他のオプションもたくさんあります。ローカルからリモートへ、リモートからローカルに、ローカルからローカルにファイルを転送できます。最も重要な機能の1つは、正しいオプションを指定すると、コマンドを中断して再開することができ(同じコマンドラインを再実行し)、以前の場所から続行することです。
あなたの目的に応じて、次のオプションが興味深いことがあります。
-v
:詳細、何が起こったのかを示す内容は複数回提供できますが、通常は一度で十分です。-n
:テストの実行、テストには非常に重要ですが、何もしないでください(結合-v
)! !-c
:チェックサムを使用してコピーする内容を決定します。--remove-source-files
:成功的に転送されたファイルを削除します(@brawny84が指摘したように、私はそれについて知らず、最初に読んだマニュアルページには見つかりませんでした)。
dest
したがって、このコマンドはチェックサムがそのファイルsource
(名前に対応)とは異なるすべてのファイルを上書きします。
rsync -a -c -v --remove-source-files -n /path/to/source /path/to/dest
rsync -a -c -v --remove-source-files /path/to/source /path/to/dest
利点
- チェックサムで使用
- トライアルモードがあります
- 実際に欠落しているすべてのファイルとソースとは異なるファイルをターゲットにコピーします。
- 中断して再起動できます。
- すべてのファイルをコピーしたくない場合は、srcの特定のファイルを無視する除外オプションがあります。
- 転送されたソースファイルを削除できます。
欠点
- ??
3番目の考え:fdupes
プログラムfdupes
重複ファイルを一覧表示するように設計されています。デフォルトではmd5sumを確認します。
利点
- md5を使用してファイルを比較します。
--delete
重複したアイテムの1つを削除するオプションがあります
欠点
- それは比較する各ファイルを送信する他のすべてのファイルしたがって、dest自体の内部に重複したファイルがある場合は、そのファイルも一覧表示されます。
- 削除モードは対話型のようです。同じファイルの各セットを確認する必要があります。これは大きなディレクトリツリーでは不可能です。
- 非対話モードでは、各同じファイルセットから最初のファイルを除くすべてのファイルが削除されます。しかし、最初のファイルが何であるかはわかりません(ソースファイルにありますか、それともターゲットファイルにありますか?)。
最後の考え:実際に自分のシェルスクリプトを書いてデバッグするのに苦しんでください。
手動で行う必要がある場合は、次のように始めます。 私はこれをテストしていません。まず試してみてls
、ブレーキがかかっていることを確認してください!
#!/bin/bash
# first require that the source and dest dirs
# are given as arguments to the script.
src=${1:?Please give the source dir as first argument}
dest=${2:?Please give the destination dir as second argument}
# go to the source directory
cd "$src"
# This assumes that there are no newlines in filenames!
# first find all plain files in the current dir
# (which should be $src)
# then use xargs to hand the filenames to md5sum
# pipe the md5 sums into a subshell
# go to the dest in the subshell
# read the md5sums from stdin and use md5sum -c to check them
# After the subshell filter lines to only keep those that end in "OK"
# and at the same time remove the "OK" stuff after the file name
# use xargs to hand these file names to ls or rm.
find . -type f | \
xargs md5sum | \
( cd "$dest" && md5sum -c ) | \
sed -n 's/: OK$//p' | \
xargs ls
最後の行には、ls
スキャンに合格したすべてのファイルが一覧表示されます。に置き換えると、rm
ソースディレクトリ(以降の現在のディレクトリ)から削除されますcd "$src"
。