異なるファイルを開かずに比較するにはどうすればいいですか?

異なるファイルを開かずに比較するにはどうすればいいですか?

ディレクトリAとBが2つあり、それぞれに多くのサブディレクトリが含まれています。

geom001, geom002 ....etc

各サブディレクトリには、results という名前のファイルが含まれています。ファイルを開かずに、A の各ファイルと B の各ファイルを比較し、B の 1 つ以上のファイルに類似するファイルが A に 1 つ以上あるかどうかを調べます。ループで次のようなコマンドを使用して、すべてのファイルを検索するにはどうすればよいでしょうか。

cmp --silent  file1 file2  || echo "file1 and file2 are different"

答え1

ファイルがまったく同じであれば、 もmd5sumまったく同じになるため、次のように使用できます。

find A/ B/ -type f -exec md5sum {} + | sort | uniq -w32 -D

md5sum は常に 128 ビット (または 16 バイト、または 32 桁の 16 進数) の長さで、md5sumプログラムの出力では 16 進数が使用されます。そのため、コマンド-w32のオプションを使用してuniq、各行の最初の 32 文字のみを比較します。

これは印刷されます全て一意でない md5sum を持つファイル。つまり重複です。

注意: これは、A/ または B/ のどこにあっても重複ファイルを検出します。したがって、 と/A/subdir1/fileA/subdir2/otherfile同じ場合は、それらが印刷されます。重複ファイルが複数ある場合は、それらすべてが印刷されます。

出力から md5sum を削除するには、たとえば、awk '{print $2}'またはをcutまたはなどでパイプします。これらは、またはなどsedでの連想配列 (別名「ハッシュ」) のキーとしてさらに処理する際に便利なので、出力に残しておきました。awkperl

答え2

これでほぼ解決すると思います。A の results という名前のすべてのファイルと B の results という名前のすべてのファイルを比較して、cmp 出力を一覧表示します。

find ./A -name results | xargs -I REPLACESTR find ./B -name results -exec cmp REPLACESTR {} \;

答え3

質問/リクエストの一見したところの課題は、おそらく再帰の側面です。

これcmpが適切なユーティリティであり、比較する両方のフォルダー/ディレクトリが1同じ2構造 (つまり、同じファイルとフォルダー) であり、同じルート パス内に存在すると仮定すると、次のようなものを試すことができます。

#!/bin/bash
ROOT=$PWD ; # #// change to absolute path eg: /home/aphorise/my_files
PWD1="1/*" ;
PWD2="2/*" ;

# #// Get lengths of seperators
IFS=/ read -a DP <<< ${ROOT} ;
PLEN1=${#DP[*]} ;
IFS=/ read -a DP <<< ${PWD1} ;
PLEN1=$(echo "${#DP[*]}" + $PLEN1 - 1 | bc) ;
IFS=/ read -a DP <<< ${PWD2} ;
PLEN2=${#DP[*]} ;

# #// Set absolute paths:
PWD1="${ROOT}/${PWD1}" ;
PWD2="${ROOT}/${PWD2}" ;
DIFFS=0 ;

function RECURSE()
{
    for A_FILE in $1 ; do
        if [ -d $A_FILE ] ; then
            RECURSE "$A_FILE/*" ;
        else
            IFS=/ read -a FP <<< ${A_FILE} ;
            B_FILE="${PWD2:0:${#PWD2}-${#PLEN2}}$( IFS=/ ; printf "%s" "${FP[*]:$PLEN1:512}"; )" ;
            if ! cmp ${A_FILE} ${B_FILE} 1>/dev/null ; then printf "$A_FILE --> $B_FILE <-- DIFFER.\n" ; ((++DIFFS)) ; fi ;
        fi ;
    done ;
}

printf "Starting comparison on $PWD1 @ $(date)\n\n" ;
RECURSE "${PWD1[*]}" ;
if ((DIFFS != 0)) ; then printf "\n= $DIFFS <= differences detected.\n" ; fi ;
printf "\nCompleted comparison @ $(date)\n" ;

アップデート:

追加のフィードバックを受け取った後、別のスクリプトを実行して、ディレクトリ内のすべてのファイルを無条件に比較します12

#!/bin/bash
PWD1="$PWD/1/*" ;
PWD2="$PWD/2/*" ;
DIFFS=0 ;
NODIFFS=0 ;

printf "Starting comparison on $PWD1 @ $(date)\n\n" ;

FILES_A=$(find ${PWD1} -type f) ;
FILES_B=$(find ${PWD2} -type f) ;

for A_FILE in ${FILES_A[*]} ; do
        for B_FILE in ${FILES_B[*]} ; do
                if ! cmp ${A_FILE} ${B_FILE} 1>/dev/null ; then
                        printf "$A_FILE & $B_FILE <- DIFFER.\n" ;
                        ((++DIFFS)) ;
                else
                        printf "\n-> SAME: $A_FILE & $B_FILE\n" ;
                        ((++NODIFFS)) ;
                fi ;
        done ;
done ;

printf "\n= $DIFFS <= differences detected - & - $NODIFFS <= exact matches.\n" ;
printf "\nCompleted comparison @ $(date)\n" ;

関連情報