체크섬 차이를 유지하면서 한 폴더에서 동일한 파일이 제거되도록 두 폴더를 병합하는 방법은 무엇입니까?

체크섬 차이를 유지하면서 한 폴더에서 동일한 파일이 제거되도록 두 폴더를 병합하는 방법은 무엇입니까?

다른 시점의 드라이브에서 복구해야 하는 상황이 있습니다. 이 드라이브는 파일 존재 여부가 다를 뿐만 아니라 일부 손상이 있을 수 있으며 그 중 다수는 명백히 손상되었습니다.

왼쪽 폴더의 이름은 "A", 오른쪽 폴더의 이름은 "B"입니다.

나는 다음과 같이 두 이미지를 병합할 책임이 있습니다.

  1. B에는 있지만 A에는 없는 모든 파일을 A로 이동해야 합니다.
  2. 두 위치에 존재하고 동일한 모든 파일은 B에서 삭제되어야 하며 마지막으로
  3. 서로 다른 체크섬을 가진 파일은 B에 남아 있어야 A와 B 간에 서로 다른 파일을 수동으로 비교할 수 있습니다. 그러나 체크섬이 다른 파일(예: 실제 콘텐츠) 외에는 B에 파일이 없어야 합니다. 다른 콘텐츠를 유지하세요.

노트: 현재 시점에서는 날짜가 거의 중요하지 않습니다.좋아요메타데이터에 이전 날짜를 유지합니다.

어떻게 하면 깔끔하게 처리할 수 있나요? 안타깝게도 수십 테라바이트의 데이터에 대해 이 작업을 수행해야 하므로 이를 자동화하는 방법을 모른다면 프로세스가 매우 길어질 것입니다. 내용의 90-95%가 동일한 것으로 나타나므로 수동 비교를 준비하려면 "설정하고 잊어버리는" 접근 방식을 개발해야 합니다.

답변1

2단계와 3단계가 가장 어려울 것 같으니 그 단계부터 시작하겠습니다.

rdfind중복된 파일을 찾아주는 도구가 있습니다 . 중복이 감지되면 어떻게 할지 결정합니다. 귀하의 경우에는 B에서 삭제하려고 합니다 rdfind -deleteduplicates true A B. A와 B에 동일한 파일이 있으면 A에 파일을 유지합니다. 다른 옵션은 복사본을 하드 또는 소프트 링크로 바꾸거나 결과를 보고하는 것입니다.

그런 다음 B에 보관된 파일은 B에 고유하거나 B의 파일이 A의 파일과 다릅니다. 유일한 파일을 B에서 A:로 이동하고 mv -i B/* A/덮어 no쓸지 묻는 메시지가 나타날 때마다 응답합니다. 자동화를 사용하여 이를 수행할 수 있습니다 yes no | mv -i B/* A/. GNU mv를 사용하는 경우 mv --no-clobber B/* A/.

물론 실제 데이터를 사용하기 전에 연습이 필요합니다. A와 B의 파일을 가리키는 하드 링크 트리를 쉽게 만들고 mkdir training; cp -lr A training; cp -lr B training거기서 연습할 수 있습니다.

답변2

방법은 간단하지만 A에 누락된 파일이 많으면 효율성이 매우 떨어집니다. 각 단계를 순서대로 따르시면 됩니다. 나는 디렉토리와 일반 파일만 있다고 가정합니다(특수 파일에 대한 메타데이터를 비교하는 것은 더 많은 작업을 통해 수행할 수 있음). 경고: 테스트되지 않은 코드입니다.

먼저 B에는 있지만 A에는 없는 파일을 A로 복사합니다. 가능한 경우 메타데이터(타임스탬프, 권한)를 보존하세요.

rsync -a --ignore-existing B A

둘째, B에서 중복된 항목을 제거합니다. 이 시점에서 원래 A에 존재하지 않았던 파일은 이제 동일합니다.

cd B
find . -type f -exec sh '
  for x; do
    if cmp -s "$x" "$0/$x"; then rm "$x"; fi
  done
' /path/to/A {} +

(선택 사항) B에서 빈 디렉터리를 제거합니다.

find B -depth -type d -exec rmdir {} + 2>/dev/null

2단계에서는 A에서 이미 누락된 모든 파일이 이제 B에서 복사, 비교 및 ​​삭제되기 때문에 이는 비효율적입니다. A에서 많은 파일이 누락된 경우 B로 단일 전달하여 파일을 A로 이동하고 중복 항목을 제거하는 것이 더 효율적입니다. 이는 A와 B가 동일한 파일 시스템에 있는 경우 특히 그렇습니다. 따라서 소스를 복사한 다음 삭제하는 것보다 파일을 이동하는 것이 더 저렴합니다.

답변3

나는 당신의 주장에 이의를 제기하는 것부터 시작하겠습니다. 당신은 모든 것을 한 단계로 처리하려고 노력하고 있습니다. 파일 복구를 시작하기 전에 복원된 시스템이 어떤 모습일지 아는 것이 좋습니다.

실제로 처음에 차이를 알아내는 것은 생각보다 쉽습니다.

1 단계

디스크에 있는 각 파일의 해시 값을 가져옵니다. 무슨 일이 있어도 해야 합니다. 그러니 그것을 끝내고 끝내는 것이 좋습니다. 하드 링크가 너무 많지 않으면 다음 명령이 잘 작동합니다.. 디렉토리의 이름이 /media/A이고 이라고 가정합니다 /media/B.

cd /media/A
find . -type f -exec sha256sum {} + > ~/hashes.txt

그러면 디스크의 모든 일반 파일에 대한 해시가 생성됩니다. 파일이 하드 링크된 경우 각 이름 아래에 표시됩니다(각 이름에 대해 한 번 검색됩니다).

2 단계

변경 사항 식별

cd /media/B
sha256sum -c ~/hashes.txt > ~/check.txt

check.txt에는 이제 세 가지 유형의 줄이 포함됩니다.

  • good/file: OK
  • missing/file: FAILED open or read
  • changed/file: FAILED

3단계

바로 가기로 다음 명령을 사용하여 누락된 파일을 모두 복사할 수 있습니다.

rsync -a --ignore-existing /media/A/ /media/B/

4단계

그러면 파일 변경에 대해서만 걱정하면 됩니다.

grep 'FAILED$' ~/check.txt | while read file ; do
    echo "${file%: FAILED}"
done > ~/changed.txt

이렇게 하면 각 줄에 파일 이름이 있는 selected.txt가 제공됩니다. 각각은 두 시스템 모두에서 변경된 파일입니다.

changed.txt이제 보관할 파일과 B에서 A로 덮어쓸 파일을 정렬하고 결정하는 것은 사용자의 몫입니다 .

답변4

파일 이름에 "줄 바꿈"이 없다고 가정하면 다음과 같이 작동합니다.

cd B
find . -type f -print | while read f
do
    [[ -f "A/$f" ]] || { echo mv "$f" "A/$f" ; continue; }
    cmp "$f" "A/$f" && echo rm "$f"
done

실행하고 괜찮아 보이면 "echo" 단어를 제거하여 실제 명령을 실행하십시오.

관련 정보