ディレクトリの md5 チェックサムを計算するにはどうすればよいですか?
質問
特定のタイプのすべてのファイルの概要の md5 チェックサムを計算する必要があります (*.py
例) ディレクトリとすべてのサブディレクトリの下に配置されます。
そのための最良の方法は何でしょうか?
編集: 提案されたソリューションは非常に優れていますが、これはまさに私が必要とするものではありません。を取得するための解決策を探しています 単一の概要 すべてのサブディレクトリの内容を含む、ディレクトリ全体を一意に識別するチェックサム。
解決
find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum
findコマンドリストの.pyで終わるすべてのファイル。 md5sumは、それぞれの.pyファイルに対して計算されます。 AWKは(ファイル名、一意でない可能性が無視)MD5SUMSピックオフするために使用されます。 MD5SUMSがソートされています。 このソートされたリストのmd5sum返されます。
私はテストディレクトリをコピーすることによって、これをテストしてみます:
rsync -a ~/pybin/ ~/pybin2/
私は〜/ pybin2内の一部のファイルの名前を変更します。
find...md5sum
コマンドは、両方のディレクトリのために同じ出力を返します。
2bcf49a4d19ef9abd284311108d626f1 -
他のヒント
md5sum
に飛ぶと、パイプのtarアーカイブファイルを作成します。
tar c dir | md5sum
これはあなたのファイルとサブディレクトリの設定に一意である必要があり、単一のmd5sumを生成します。何のファイルがディスク上に作成されません。
ire_and_curses の使用提案 tar c <dir>
いくつかの問題があります:
- tar は、ファイルシステムに格納されている順序でディレクトリ エントリを処理します。この順序を変更する方法はありません。これは、異なる場所に「同じ」ディレクトリがある場合、実質的にまったく異なる結果をもたらす可能性があり、これを修正する方法がわかりません(tar は入力ファイルを特定の順序で「ソート」できません)。
- 私は通常、groupid と ownerid の番号が同じかどうかを気にしますが、必ずしもグループ/所有者の文字列表現が同じかどうかは気にしません。これは、たとえば
rsync -a --delete
行います:これは事実上すべてを同期します (xattrs と acls を除く) が、文字列表現ではなく ID に基づいて所有者とグループを同期します。したがって、必ずしも同じユーザー/グループが含まれるとは限らない別のシステムに同期した場合は、--numeric-owner
タールにフラグを立てる - tar には、チェックしているディレクトリ自体のファイル名が含まれますが、これには注意が必要です。
最初の問題に対する修正がない限り (または、それが自分に影響を与えないと確信できない限り)、私はこのアプローチを使用しません。
の find
上記で提案されたベースのソリューションも、ディレクトリではなくファイルのみを含むため、役に立ちません。チェックサムで空のディレクトリを念頭に置く必要がある場合、これが問題になります。
最後に、照合順序がシステム間で異なる可能性があるため、提案されたソリューションのほとんどは一貫して並べ替えられません。
これが私が思いついた解決策です:
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
このソリューションに関するメモ:
- の
LC_ALL=C
システム間で信頼性の高い並べ替え順序を確保することです - これは、「named
withanewline」というディレクトリと、「named」および「withanewline」という 2 つのディレクトリを区別しませんが、そのようなことが起こる可能性は非常に低いように思われます。通常、これを次のように修正します。
-print0
の旗find
しかし、ここでは他のことが起こっているので、コマンドを価値以上に複雑にする解決策しかわかりません。
追伸:私のシステムの 1 つは限られたビジーボックスを使用しています find
サポートしないもの -exec
または -print0
フラグを追加し、ディレクトリを示すために「/」を追加しますが、findutils find はそうでないようなので、このマシンの場合は次を実行する必要があります。
dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
幸いなことに、名前に改行が含まれるファイル/ディレクトリはないため、これはそのシステムでは問題になりません。
あなただけのファイルと空でないディレクトリを気にしている場合は、これがうまく機能します:
find /path -type f | sort -u | xargs cat | md5sum
は、完全を期すために、 md5deep(1)にあります。それが原因*の.pyフィルタ要件に直接適用可能ではないですが、検索(1)と一緒に罰金を行う必要があります。
私にとって最もうまくいった解決策:
find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum
それが私にとって最も効果的だった理由:
- スペースを含むファイル名を処理する
- ファイルシステムのメタデータを無視します
- ファイルの名前が変更されたかどうかを検出します
他の回答に関する問題:
ファイルシステムのメタデータは次の場合には無視されません。
tar c - "$path" | md5sum
スペースを含むファイル名は処理されず、ファイル名が変更されたかどうかも検出されません。
find /path -type f | sort -u | xargs cat | md5sum
あなたはディレクトリ全体にまたがる1つのmd5sumをしたい場合は、私は
のような何かをするだろうcat *.py | md5sum
チェックサム内容とそのファイル名の両方を含む、すべてのファイル、
grep -ar -e . /your/dir | md5sum | cut -c-32
同上の、だけを含む*の.pyファイルの
grep -ar -e . --include="*.py" /your/dir | md5sum | cut -c-32
あなたがしたい場合は、また、シンボリックリンクをたどることができます。
grep -aR -e . /your/dir | md5sum | cut -c-32
その他のオプションを使用すると、grepをして使用して検討することもできます。
-s, --no-messages suppress error messages
-D, --devices=ACTION how to handle devices, FIFOs and sockets;
-Z, --null print 0 byte after FILE name
-U, --binary do not strip CR characters at EOL (MSDOS/Windows)
GNU見つける
find /path -type f -name "*.py" -exec md5sum "{}" +;
技術的にはあなたしかls -lR *.py | md5sum
を実行する必要があります。誰かがファイルを変更し、元の日付にそれらをバックに触れると、ファイルのサイズを変更することはありません心配している場合を除き、ファイルが変更された場合、ls
からの出力はあなたを教えてください。あなたは印刷する時間や修正を作成する時間を得るために、いくつかのより多くのコマンドラインパラメータを必要とする場合がありますので、私のUNIX-fooが弱いです。ファイルのアクセス権が変更されている(と私はあなたがそれを気にしない場合はこれをオフにするスイッチがあります確信している)場合ls
にも教えてくれます。
私はこれを行うにはHashCopyを使用しています。これは、単一のファイルまたはディレクトリにMD5とSHAを生成し、検証することができます。それはwww.jdxsoftware.orgからダウンロードすることができます。
md5deep
を使用します:
md5deep -r FOLDER | awk '{print $1}' | sort | md5sum
私は同じ問題を抱えていましたカレントディレクトリを介して、またはサブディレクトリから言っ引数は$ 1に渡された場合、
#!/bin/bash
if [ -z "$1" ] ; then
# loop in current dir
ls | while read line; do
ecriv=`pwd`"/"$line
if [ -f $ecriv ] ; then
md5sum "$ecriv"
elif [ -d $ecriv ] ; then
sh myScript "$line" # call this script again
fi
done
else # if a directory is specified in argument $1
ls "$1" | while read line; do
ecriv=`pwd`"/$1/"$line
if [ -f $ecriv ] ; then
md5sum "$ecriv"
elif [ -d $ecriv ] ; then
sh myScript "$line"
fi
done
fi
あなたが本当にファイルシステムの属性から、いくつかのtarのバージョンのビットレベルの違いからindependanceたい場合は、cpioのを使用することができます:
cpio -i -e theDirname | md5sum
2つのソリューションがあります:
作成します:
du -csxb /path | md5sum > file
ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum > /tmp/file
チェック:
du -csxb /path | md5sum -c file
ls -alR -I dev -I run -I sys -I tmp -I proc /path | md5sum -c /tmp/file
md5sum
は私のためにうまく働いたが、私はsort
とファイル名をソートに問題がありました。だからではなく、私はmd5sum
結果によって並べ替え。私はまた、同等の結果を作成するためにいくつかのファイルを除外するために必要な。
find . -type f -print0 \
| xargs -r0 md5sum \
| grep -v ".env" \
| grep -v "vendor/autoload.php" \
| grep -v "vendor/composer/" \
| sort -d \
| md5sum