
두 개의 디렉토리 A와 B가 있습니다. 각각에는 많은 하위 디렉터리가 포함되어 있습니다.
geom001, geom002 ....etc
각 하위 디렉터리에는 results라는 파일이 포함되어 있습니다. A의 각 파일을 열지 않고 B의 각 파일과 비교하고 B의 하나 이상의 파일과 유사한 파일이 A에 있는지 확인하고 싶습니다. 다음과 같은 명령을 어떻게 사용할 수 있습니까? 모든 파일을 검색하려면 루프를 수행해야 합니까?
cmp --silent file1 file2 || echo "file1 and file2 are different"
답변1
파일이 정확히 동일하면 해당 파일의 md5sum
s도 정확히 동일하므로 다음을 사용할 수 있습니다.
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/file
및 A/subdir2/otherfile
가 동일하면 계속 인쇄됩니다. 중복된 내용이 여러 개인 경우 모두 인쇄됩니다.
awk '{print $2}'
예를 들어, 또는 등으로 cut
파이프 하여 출력에서 md5sum을 제거할 수 있습니다. 나중에 sed
연관 배열(일명 '해시')에 대한 유용한 키이기 때문에 출력에 남겨 두었습니다 . 처리.awk
perl
답변2
내 생각엔 이것이 당신을 더 가까워지게 할 것 같아요. B의 결과라는 모든 파일과 비교하여 A의 결과라는 모든 파일에 대한 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" ;
업데이트:
추가 피드백을 받은 후 다른 스크립트를 사용하여 디렉터리의 모든 파일을 무조건 비교 합니다 1
.2
#!/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" ;