フォルダとフォルダ構造の比較

フォルダとフォルダ構造の比較

写真やフィルムが入ったカメラのSDカードがあります。私のメインボックスには、次のディレクトリ名を持つフォルダ構造があります。Images / YYYY-MM-descriptionと、時には別の名前のサブフォルダがあります。 SDカードのファイル名は、フォルダのファイル名と同じです。

私のボックスにSDカードのすべてのファイルが含まれていることを確認するために、SDカードをフォルダ構造と比較(チェックサム)したいと思います。私はMD5ingについて考えましたが、ユースケースに合ったアルゴリズムで十分です。

rsyncorを使用しようとしましたが、diffボックスに複数のレイヤーがあるため、解決策が見つかりませんでした。

もしそうなら、システムはDebianです。

答え1

md5deepを使用できます。

sudo apt-get install md5deep

まず、結果をフォルダに保存します。

md5deep -r -s /dir1> dir1sums

今、他のフォルダと比較してみてください。

md5deep -r -X dir1sums /dir2

出力がなければ、ディレクトリが同じであることを意味します。それ以外の場合は、他のファイルのハッシュが表示されます。

答え2

私は次の仮定をします:

1)すべてのファイル名は一意です。

2)欠落しているファイルのみを確認したい場合(各デバイスのファイルに同じmd5合計がある場合、つまり写真が破損している場合)

3)ファイルはこのシステムでのみ欠落する可能性があります。 SDカードにはデフォルトですべてのファイルがあります。

前提1に加えて、スクリプトを変更して2つの場所のいずれかで単一のファイルを見つけることも、各ファイルのペアに対してmd5クロスチェックを実行することもできます。

このようにして、すべてのファイル名を選択し、次を使用してueファイル名のfindリストを確認できます。uniq

#!/bin/bash

#load all file names from local dir as array:
pics_local=( $( find /path/to/dir/ -type f -printf "%f\n" ) )
#load all file names from SD card as array:
pics_SD=( $( find /mnt/SD/ -type f -printf "%f\n" ) )
#see if files are only in one of them,
#i.e. if file names appear only once (save as array):
singulars=( $( printf "%s\n" ${pics_local[@]} ${pics_SD[@]} |\
            sort | uniq -u ) )
#print list of missing files with full paths using find:
for (( i=0 ; i<=${#singulars[@]}-1 ; i++ )) ; do
    find /mnt/SD/ -type f -name "${singulars[$i]}"
done

更新:ファイルごとにmd5sumを使用するスクリプト:SDにすべてのファイルがあり、ローカルディレクトリから見つからないファイルを検索します。すべてのローカルファイルはSDファイルと同じです(md5と一致しない対応するファイルを除く)。

#!/bin/bash

#load file names and md5sums of files on SD card into array
files_SD=( $( find /mnt/SD/ -type f ) )
md5_SD=( $( find /mnt/SD/ -type f -exec md5sum {} + | cut -d' ' -f1 ) )
#load md5sums of files in local folder into array:
md5_loc=( $( find /local/dir/ -type f -exec md5sum {} + | cut -d' ' -f1 ) )

#check for the very unlikely possibility of md5sums
#matching for more than two files
#IMHO: can be safely skipped
if [[ $(sort <( printf '%s\n' ${md5_loc[@]} ${md5_SD[@]}) |\
      uniq -c | awk ' $1 >= 3 ' ) ]] ; then
  echo "md5 sums matching for more than 2 files!"
  echo "critical error, aborting"
  exit
fi

singular_md5s=( $( printf '%s\n' ${md5_loc[@]} ${md5_SD[@]} | sort | uniq -u ) )
for (( i=0 ; i<=${#singular_md5[@]}-1 ; i++ )) ; do
  #assume SD card has all files
  #print file that is missing in local folder:
  #1) find where it is in the array:
  n=$(( $(grep -n "${singular_md5s[$i]}" <( printf '%s\n' ${md5_SD[@]} ) | cut -d: -f1 )-1 ))
  #2) print file name
  echo "${files_SD[$n]} missing on local folder"
done

関連情報