이것을 참조하세요게시 체크섬을 기반으로 중복 파일 찾기 및 제거, 복사 작업을 수행하는 방법을 수정한 다음 대상 파일에 대해 파일 무결성 검사를 수행하고 싶습니다.
SOURCE = /path/to/Source
DEST = /path/to/Destination
# filecksums containing the md5 of the copied files
declare -A filecksums
for file in "$@"
do
[[ -f "$file" ]] || continue
# Generate the checksum
cksum=$(cksum <"$file" | tr ' ' _)
# Can an exact duplicate be found in the destination directory?
if [[ -n "${filecksums[$cksum]}" ]] && [[ "${filecksums[$cksum]}" != "$file" ]]
then
rm -f "$file"
else
echo " '$file' is not in '$DEST'" >&2
fi
done
md5 체크섬 비교 결과를 사용 rm -f
하고 체크섬이 동일한 경우에만 소스 파일을 허용하고 싶습니다. 차이점이 있으면 결과를 에코하고 이스케이프 처리하고 싶습니다. rsync
또 다른 옵션일 수도 있지만 로컬 간 파일 전송에 대해 강제로 체크섬 비교를 수행하면 문제가 발생할 수 있다고 생각합니다.
고쳐 쓰다
@Lucas의 답변을 기반으로 rsync 사용을 조사했습니다. 파일을 일괄 전송하는 대신 확인 mv /data1/* /data2/
하고, 완료된 작업을 보고하고 확인 후 삭제하는 방식 으로 파일을 보다 안정적으로 전송할 수 있는 옵션이 있는 것 같습니다 . 커뮤니티 회원들이 지적했듯이 이는 정의를 좁힐 수 있습니다.
답변1
파일에 관심이 있고 어지럽히는 것을 원하지 않는다면 처음에 이와 같은 것을 구현하는 것이 어려울 수 있습니다. 따라서 bash에서 완전한 스크립트를 작성하는 것에 대한 몇 가지 대안이 있습니다. 이러한 다소 복잡한 명령줄(oneliners)이 귀하의 경우에 도움이 될 수 있습니다.
귀하의 질문에 불확실성이 있습니다. 비교하고 싶습니까?각소스 파일에는 다음이 포함됩니다.모든파일이 대상에 있습니까, 아니면 "일치하는" 파일 이름을 가진 파일만 포함되어 있습니까? (이것은 /path/to/src/a
AND 비교 이지만 AND 등은 아닙니다 /path/to/dest/a
. )/path/to/src/b
/path/to/dest/b
/path/to/src/a
/path/to/dest/b
나는 당신이 경로가 일치하는 파일만을 비교하고 싶다고 가정합니다!
처음 생각:diff
오래된 것이 더 좋다diff
디렉터리는 재귀적으로 비교할 수 있습니다. -q
옵션을 사용하여 어떤 파일이 다른지, 어떤 파일이 다른지 확인할 수도 있습니다.어떻게그들은 다르다.
diff -r -q /path/to/source /path/to/dest
결점
- 이를 위해서는긴시간은 하드 드라이브의 크기에 따라 다릅니다.
- 오래된 파일은 삭제되지 않습니다.
- 출력을 구문 분석하기가 쉽지 않습니다.
이점
- 파일은 삭제되지 않습니다 :)
따라서 관심있는 파일에 차이가 없음을 수동/시각적으로 확인한 후 rm -rf /path/to/source
.
두 번째 생각:( rsync
편집: 아마도 지금은 이것이 최고일 것입니다)
rsync
모든 복제 명령줄 도구의 마스터입니다(제 생각에는;). 귀하의 질문에 대한 의견에서 언급했듯이 하나의 --checksum
옵션이 있지만 다른 옵션도 많이 있습니다. 로컬에서 원격으로, 원격에서 로컬로, 로컬에서 로컬로 파일을 전송할 수 있습니다. 가장 중요한 기능 중 하나는 올바른 옵션을 제공하면 명령을 중단하고 다시 시작할 수 있으며(동일한 명령줄을 다시 실행) 이전 위치에서 계속된다는 것입니다!
귀하의 목적에 따라 다음 옵션이 흥미로울 수 있습니다.
-v
: 자세한 내용, 무슨 일이 일어났는지 보여주는 내용은 여러 번 제공될 수 있지만 일반적으로 한 번이면 충분합니다.-n
: 시험 실행, 테스트하는 데 매우 중요하지만 아무 것도 하지 마십시오(결합-v
)! !-c
: 체크섬을 사용하여 복사할 내용을 결정합니다.--remove-source-files
:성공적으로 전송된 파일을 제거합니다(@brawny84가 지적했듯이 저는 그것에 대해 몰랐고 처음 읽은 매뉴얼 페이지에서 찾지 못했습니다).
dest
따라서 이 명령은 체크섬이 source
해당 파일(이름에 해당)과 다른 모든 파일을 덮어씁니다 .
rsync -a -c -v --remove-source-files -n /path/to/source /path/to/dest
rsync -a -c -v --remove-source-files /path/to/source /path/to/dest
이점
- 체크섬과 함께 사용됨
- 트라이얼 모드가 있습니다
- 실제로 누락된 모든 파일과 소스와 다른 파일을 대상으로 복사합니다.
- 중단하고 다시 시작할 수 있습니다.
- 모든 파일을 복사하고 싶지 않은 경우 src의 특정 파일을 무시하는 제외 옵션이 있습니다.
- 전송된 소스 파일을 삭제할 수 있습니다.
결점
- ??
세 번째 생각:fdupes
프로그램fdupes
중복 파일을 나열하도록 설계 중입니다. 기본적으로 md5sum을 확인합니다.
이점
- md5를 사용하여 파일을 비교합니다.
--delete
중복 항목 중 하나를 제거하는 옵션이 있습니다
결점
- 그것은 비교한다각파일을 제출하다다른 모든 파일따라서 dest 자체 내부에 중복된 파일이 있으면 해당 파일도 나열됩니다.
- 삭제 모드는 대화형인 것처럼 보입니다. 동일한 파일의 각 세트를 확인해야 합니다. 이는 큰 디렉터리 트리에서는 불가능할 수 있습니다.
- 비대화형 모드는 각 동일한 파일 세트에서 첫 번째 파일을 제외한 모든 파일을 삭제합니다. 하지만 첫 번째 파일이 무엇인지는 알 수 없습니다(소스 파일에 있습니까, 아니면 대상 파일에 있습니까?).
마지막 생각: 실제로 자신만의 쉘 스크립트를 작성하고 디버깅하는 고통을 겪어보세요.
수동으로 수행해야 한다면 다음과 같이 시작하겠습니다. 나는 이것을 테스트하지 않았습니다. 먼저 시도해 ls
보고 브레이크가 걸리는지 확인하십시오!
#!/bin/bash
# first require that the source and dest dirs
# are given as arguments to the script.
src=${1:?Please give the source dir as first argument}
dest=${2:?Please give the destination dir as second argument}
# go to the source directory
cd "$src"
# This assumes that there are no newlines in filenames!
# first find all plain files in the current dir
# (which should be $src)
# then use xargs to hand the filenames to md5sum
# pipe the md5 sums into a subshell
# go to the dest in the subshell
# read the md5sums from stdin and use md5sum -c to check them
# After the subshell filter lines to only keep those that end in "OK"
# and at the same time remove the "OK" stuff after the file name
# use xargs to hand these file names to ls or rm.
find . -type f | \
xargs md5sum | \
( cd "$dest" && md5sum -c ) | \
sed -n 's/: OK$//p' | \
xargs ls
마지막 줄에는 ls
검사를 통과한 모든 파일이 나열됩니다. 로 바꾸면 rm
소스 디렉터리( 이후의 현재 디렉터리)에서 제거됩니다 cd "$src"
.