2つのフォルダ内のファイルのmd5sum

2つのフォルダ内のファイルのmd5sum

1 つのコマンドで md5sum を使用して 2 つのフォルダー内のすべてのファイルを比較しようとしています。Debian では次のようになります (bash)。

$ cd ~/FOLDER1
$ md5sum ~/FOLDER2/* | md5sum -c -

最初の md5sum からのハッシュの出力が 2 番目の md5sum に渡され、入力ファイルとして使用されるという考え方です。ただし、これをテストすると、FOLDER2 内の各ファイルをそれ自体と比較し、それぞれに対して「OK」を返すだけであることがわかります。これが機能しない理由は、最初の md5sum からのファイル名出力にフル パスが含まれているためだと思います。調べてみましたmd5deepが、これについては何も役に立ちませんでした。1 つのフォルダーに対して md5sum を実行し、結果をファイルに書き出して、そのファイルを 2 番目の md5sum の入力として使用することは可能です。2 つのコマンドを使用してファイルを書き出すのではなく、パイプを介して 1 行ですべてを実行したいと考えていました。

編集: 受け入れられた回答ここ( を使用) すると、必要な処理が実行されるかもしれませんが、バイナリ ファイルを (正しく) 比較するdiffかどうかはわかりません。diff

編集: md5sum を使用して必要な出力 (ファイル名と「OK」が表示される) を取得するために、バッチ ファイルを作成することにしました。 で実行しますdiffFolders.sh ~/FOLDER1 ~/FOLDER2

#!/bin/bash
HERE=$PWD
cd "$1"
md5sum * > /tmp/md5sum.cmp
cd "$2"
md5sum -c /tmp/md5sum.cmp
cd $HERE

このスクリプトは、 に存在するファイルのみを比較します~/FOLDER。に~/FOLDER2追加のファイルがある場合、それらは比較されず、それらが存在することを示す出力も表示されません。

答え1

使用できますプロセス置換2 つの md5sum の出力を diff に渡します。この場合、md5 出力はプレーン テキストなので、diff で問題ありません。次のようになります。

diff <(md5 ~/FOLDER1/* | awk '{print $4}') <(md5 ~/FOLDER2/* | awk '{print $4}')

申し訳ありませんが、私は Debian を持っていないので、これをテストできません。上記は、出力の点で若干異なる可能性がある md5 を備えた OS X でテストされています。OS X では、md5 の 4 番目の列が実際の md5 の合計であるため、これらの列のみを取得しています。

awk の代わりに を使用することもできますcutが、4 番目の列を取得するには区切り文字を変更する必要がある場合があります (これらはタブで区切られていません)。

答え2

私の .bashrc ファイルから。
とても古いもの、もっとソートされたコードを書くことができるはずです。私はそれを書き直す機会がありませんでした。(一時的な修正を目的とした他のすべてのものと同様に、永久に使用されます)私はこの恥ずかしいコードを投稿します。誰かがそれをより良くして、結果を投稿してくれることを願っています :-)

特徴 :

  • 再帰的方向横断
  • md5sum による一意性/相違のチェック
  • 更新されたファイルをフルパスでリストします

コードがすべてを物語っています。arg1 は古いディレクトリ、arg2 は新しいディレクトリです。

function find-updated-files-between-old-new(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( ( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n")
 )|sort -k1.2|tee 1>/dev/null >(uniq -us1|awk -v B="$2" 'BEGIN{sub("/$",""B)}/^-/{print B substr($0,3);
 }') >(uniq -ds1|awk -vA="$1" -vB="$2" 'BEGIN{B=g(B);A=g(A)}{
 C=substr($0,3);if(f(A)!=f(B))print B C;}function g(y){sub("/$","",y);return y}
 function f(y,z,e){e="md5sum \""y""C"\"";e|getline z;close(e);return substr(z,1,32)}' )
 ) | cat
}

関数名が示すように

function find-files-name-collision-between-dir1dir2(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n") )|sort -k 1.2 | uniq -d -s 1
}

完全を期すために

function mv-mergedir1todir2(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." && return 1;
 ( cd "$1" ; tar cf - . ) | (cd "$2" ; tar --keep-old-files xvf - )
 echo -e "Done. Duplicate filnames are not replaced. \n#Use \n# ( cd \"$1\" ; tar cf - . ) | (cd \"$2\" ; tar --overwrite xvf - ) \n#if you do not like that. "
}

このひどいコードは bashrc から削除する必要がありますが、長い間存在しています...

答え3

少し長いですが、ファイル名と、一致する場合は OK を返します。'-c' を使用する代わりに、各フォルダー内のファイルに対して md5sum を実行して出力された 2 つの文字列を比較するだけです。

for f in *; do [[ -f $f ]] && if [ $(md5sum "$f" | cut -d" " -f1) == $(md5sum dir2/"$f" | cut -d" " -f1) ]; then echo "$f" "OK"; else echo "$f" "MODIFIED"; fi; done

関連情報