두 디렉터리에서 동일한 파일 추출

두 디렉터리에서 동일한 파일 추출

다음 문제에 대한 Linux 솔루션을 찾고 있습니다.

많은 수의 파일이 포함된 두 개의 디렉터리가 제공됩니다. 모든 파일 이름은 무작위이며 두 디렉토리 모두에서 다릅니다. 그러나 두 디렉터리에 있는 일부 파일의 내용은 동일합니다.

두 디렉터리에 있는 모든 파일을 세 번째 디렉터리에 복사하고 싶습니다. ("둘 모두에서 발생"은 동일한 이름이 아니라 동일한 내용을 갖는다는 의미입니다.)

답변1

파일 이름에 공백이 없고 두 디렉터리 모두에 하위 디렉터리가 없다고 가정하면 다음은 일치하는 MD5 합계와 함께 파일 이름 쌍을 인쇄합니다.

join -o 1.2,2.2 <(md5sum $D1/* | sort) <(md5sum $D2/* | sort)

파일 이름 중 하나만 얻으려면 -o 1.2또는 를 사용하십시오 -o 2.2.

파일 이름(또는 경로)에 공백이 포함될 수 있으면 좀 더 현명하게 대처해야 합니다.

단일 디렉토리에 둘 이상의 이름을 가진 동일한 파일이 있는 경우에는 더욱 영리해야 하며 무엇을 해야 할지 정확하게 결정해야 합니다. 한 가지 가능성은 조인을 수행하기 전에 중복 항목을 필터링하는 것입니다.

join -o 1.2,2.2 <(md5sum $D1/* | sort | uniq -w16) \
                <(md5sum $D2/* | sort | uniq -w16)

사용하지 마세요sum

sum16비트 체크섬을 출력합니다. 각 디렉터리에 파일이 몇 백 개라도 있는 경우 16비트 체크섬을 비교하면 잘못된 긍정을 얻을 가능성이 높습니다. md5sum절대적으로 안전한 것은 아니지만 128비트 체크섬과 충돌할 확률은 매우 낮습니다. 의심스럽고 정말 중요한 경우에는 cmp파일도 다음과 같습니다.

join -o 1.2,2.2 <(md5sum $D1/* | sort) <(md5sum $D2/* | sort) |
while read F1 F2; do
  if cmp -s $F1 $F2; then
    cp F1 $D3
  fi
done

(다시 말하지만, 파일 이름에 공백이 있으면 작동하지 않습니다.)

답변2

이 의사 코드에 선호하는 셸을 사용하면 다음과 같습니다.

cd D1; sum * | while read l; do echo "D1 $l"; done >/tmp/foo
cd D2; sum * | while read l; do echo "D2 $1"; done >>/tmp/foo

sort -n /tmp/foo | awk '
$1 == prev_cs { echo "cp $3 dest"}
     /prev_cs = $1/
' | shell

원하는 경우 사본을 발행하기 전에 검토를 위해 awk 출력을 저장할 수 있습니다.

답변3

이것은 dups 복사를 위한 mpez0의 ans와 마찬가지로 작업을 수행할 수 있습니다.

find {tst1,tst2} -exec sum {} {} \; 2> /dev/null | sort | uniq

관련 정보