141

*.pyディレクトリとすべてのサブディレクトリの下に配置された特定のタイプのすべてのファイル(たとえば)の要約MD5チェックサムを計算する必要があります。

それを行うための最良の方法は何ですか?


提案されたソリューションは非常に優れていますが、これは私が必要としているものではありません。すべてのサブディレクトリのコンテンツを含め、ディレクトリ全体を一意に識別する単一の要約チェックサムを取得するためのソリューションを探しています。

4

16 に答える 16

169

その場でtarアーカイブファイルを作成し、それを次の場所にパイプしmd5sumます。

tar c dir | md5sum

これにより、ファイルとサブディレクトリの設定に固有の単一のMD5ハッシュ値が生成されます。ディスク上にファイルは作成されません。

于 2009-11-01T15:47:01.593 に答える
160
find /path/to/dir/ -type f -name "*.py" -exec md5sum {} + | awk '{print $1}' | sort | md5sum

findコマンドは、.pyで終わるすべてのファイルを一覧表示します。MD5ハッシュ値は、.pyファイルごとに計算されます。AWKは、MD5ハッシュ値をピックオフするために使用されます(ファイル名は無視されますが、一意ではない可能性があります)。MD5ハッシュ値がソートされます。次に、このソートされたリストのMD5ハッシュ値が返されます。

テストディレクトリをコピーして、これをテストしました。

rsync -a ~/pybin/ ~/pybin2/

〜/pybin2のいくつかのファイルの名前を変更しました。

このfind...md5sumコマンドは、両方のディレクトリに対して同じ出力を返します。

2bcf49a4d19ef9abd284311108d626f1  -
于 2009-11-01T22:15:39.627 に答える
53

ire_and_cursesの使用に関する提案にtar c <dir>は、いくつかの問題があります。

  • tarは、ファイルシステムに格納されている順序でディレクトリエントリを処理します。この順序を変更する方法はありません。異なる場所に「同じ」ディレクトリがある場合、これは事実上完全に異なる結果をもたらす可能性があり、これを修正する方法はわかりません(tarは入力ファイルを特定の順序で「ソート」できません)。
  • 私は通常、groupidとowneridの番号が同じであるかどうかを気にしますが、必ずしもgroup/ownerの文字列表現が同じであるかどうかは気にしません。これは、たとえば、rsync -a --deleteほぼすべて(xattrsとaclsを除く)を同期しますが、文字列表現ではなくIDに基づいて所有者とグループを同期します。したがって、必ずしも同じユーザー/グループを持っているとは限らない別のシステムに同期した場合は、--numeric-ownertarにフラグを追加する必要があります
  • tarには、チェックしているディレクトリのファイル名が含まれますが、これは注意が必要なことです。

最初の問題に対する修正がない限り(または、それが自分に影響を与えないことが確実でない限り)、私はこのアプローチを使用しません。

提案されたfindベースのソリューションは、ディレクトリではなくファイルのみが含まれているため、適切ではありません。これは、チェックサムで空のディレクトリを念頭に置く必要がある場合に問題になります。

最後に、照合はシステム間で異なる可能性があるため、ほとんどの提案されたソリューションは一貫してソートされません。

これは私が思いついた解決策です:

dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum

このソリューションに関する注意:

  • これLC_ALL=Cは、システム間で信頼性の高い並べ替え順序を確保することです
  • これは、「named \ nwithanewline」ディレクトリと、「named」および「withanewline」の2つのディレクトリを区別しませんが、その可能性は非常に低いようです。-print0通常、これはのフラグで修正findされますが、ここでは他のことが行われているため、コマンドを価値よりも複雑にするソリューションしか見ることができません。

PS:私のシステムの1つは、フラグもfindサポートしない限定されたbusyboxを使用しています。また、ディレクトリを示すために「/」を追加していますが、findutils findはそうではないようです。したがって、このマシンでは、次のコマンドを実行する必要があります。-exec-print0

dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum

幸いなことに、名前に改行が含まれているファイル/ディレクトリがないため、これはそのシステムの問題ではありません。

于 2011-10-20T15:27:52.487 に答える
17

空のディレクトリではなくファイルのみを気にする場合、これはうまく機能します。

find /path -type f | sort -u | xargs cat | md5sum
于 2013-04-09T21:33:31.880 に答える
10

完全を期すために、md5deep(1)があります。* .pyフィルターが必要なため、直接適用することはできませんが、find(1)と一緒に使用すると問題なく動作するはずです。

于 2013-02-04T21:58:16.413 に答える
10

私にとって最も効果的な解決策:

find "$path" -type f -print0 | sort -z | xargs -r0 md5sum | md5sum

それが私にとって最もうまくいった理由:

  1. スペースを含むファイル名を処理します
  2. ファイルシステムのメタデータを無視します
  3. ファイルの名前が変更されたかどうかを検出します

他の回答に関する問題:

ファイルシステムのメタデータは、次の場合に無視されません。

tar c - "$path" | md5sum

スペースを含むファイル名を処理せず、ファイルの名前が変更されたかどうかを検出しません。

find /path -type f | sort -u | xargs cat | md5sum
于 2015-04-08T10:28:55.073 に答える
4

ディレクトリ全体にまたがる1つのMD5ハッシュ値が必要な場合は、次のようにします。

cat *.py | md5sum
于 2009-11-01T14:39:16.910 に答える
3

コンテンツとそのファイル名の両方を含むすべてのファイルをチェックサムします

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)
于 2015-03-02T14:10:02.250 に答える
2

GNU検索

find /path -type f -name "*.py" -exec md5sum "{}" +;
于 2009-11-01T14:50:58.710 に答える
2

技術的には、を実行するだけで済みますls -lR *.py | md5sum。誰かがファイルを変更して元の日付に戻し、ファイルのサイズを変更しないことを心配していない限り、からの出力でlsファイルが変更されたかどうかがわかります。私のunix-fooは弱いので、印刷するための作成時間と変更時間を取得するために、さらにいくつかのコマンドラインパラメーターが必要になる場合があります。lsまた、ファイルのアクセス許可が変更されたかどうかも通知されます(気にしない場合は、それをオフにするスイッチがあると確信しています)。

于 2009-11-01T22:43:13.717 に答える
2

使用md5deep

md5deep -r FOLDER | awk '{print $1}' | sort | md5sum

于 2014-07-17T21:07:38.247 に答える
1

私は同じ問題を抱えていたので、ディレクトリ内のファイルのMD5ハッシュ値を一覧表示するこのスクリプトを思いつきました。サブディレクトリが見つかった場合は、そこから再度実行されます。これを行うには、スクリプトを実行できる必要があります。現在のディレクトリ、または上記の引数が$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
于 2013-03-16T21:39:43.180 に答える
1

ファイルシステムの属性や一部のtarバージョンのビットレベルの違いから本当に独立したい場合は、 cpioを使用できます。

cpio -i -e theDirname | md5sum
于 2013-11-25T13:49:11.330 に答える
1

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

于 2018-11-09T22:33:44.627 に答える
1

Gitリポジトリ内のファイル/ディレクトリに対してこれを実行して、変更されているかどうかを追跡しようとしている場合は、これが最善のアプローチであることを付け加えたいと思います。

git log -1 --format=format:%H --full-diff <file_or_dir_name>

そして、それがGitディレクトリ/リポジトリでない場合は、ire_and_cursesによる答えがおそらく最善の策です。

tar c <dir_name> | md5sum

tarただし、別のOSなどで実行すると、出力ハッシュが変更されることに注意してください。それを免れたいのであれば、一見エレガントに見えなくても、これが最善のアプローチです。

find <dir_name> -type f -print0 | sort -z | xargs -0 md5sum | md5sum | awk '{ print $1 }'
于 2020-11-03T21:35:30.627 に答える
0

さらに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
于 2016-01-29T14:34:48.453 に答える