데이터 확인 및 파일 삭제를 위한 "cp" 같은 명령어가 있나요?

데이터 확인 및 파일 삭제를 위한 "cp" 같은 명령어가 있나요?

내 휴대폰에 사진 파일이 몇 개 있어서 외장 드라이브에 백업하고 있어요. (모든 것은 Linux 노트북에 설치됩니다.)

파일을 복사했는데 꼭 mv.

그런데 이제 그 작업을 했으니, 각 파일별로 복사된 데이터가 맞는지 확인하고, 오류 없이 파일이 복사되면 휴대폰에서 해당 파일을 삭제하고 싶습니다.

그래서 제가 정말로 찾고 있는 것은 다음 cp과 같은 명령입니다 mv.

  • 대상에 파일이 없으면 파일을 복사하세요.
  • 원본과 대상 간 데이터 확인(복사 후, 파일이 아직 없는 경우)
  • 두 파일의 바이너리가 동일한 경우 소스에서 해당 파일을 제거합니다.

로 이 작업을 수행할 수 있을 것이라고 생각했지만 rsync삭제와 유사한 다양한 옵션을 살펴봤지만 "삭제"로는 아무 것도 찾아볼 수 없었습니다.원천" 대신 이 옵션은 (?) 이전/이후/중에서 파일을 삭제합니다.목적지대신에.

답변1

(참고: rsync --remove-source-files이것은 데이터의 유효성을 검사하지 않는다는 점을 제외하고 제가 찾고 있는 명령입니다.)

diff이진 비교와 관련하여 다음과 같이 할 수 있다는 것을 알았습니다 .

소스 디렉터리에서:

for f in *.jpg; do diff $f "/path/to/destination/$f"; done

소스와 대상의 바이너리를 비교합니다. 출력 없음 = 파일에 차이가 없습니다.

이는 데이터의 유효성을 검사하는 데 사용할 수 있습니다.

diff차이점을 찾지 못한 채 반환되므로 작동합니다 .0

for f in *.jpg; do diff $f "/desination/$f" && rm $f; done

반환되면 $f소스 폴더의 파일이 삭제됩니다. 즉, 파일이 동일한 바이너리입니다.diff0

새로운 명령처럼 보이도록 만드는 것이 유용할 수 있습니다 verify-rm. 이를 이라고 부르겠습니다.

드롭박스가 설치되어 있으니 6개월 뒤에 OS를 재설치할 때 백업 걱정이 없도록 스크립트를 드롭박스 폴더에 넣어두겠습니다...

$ cd ~/Dropbox && mkdir my-scripts && cd my-scripts
$ vim verify-rm

이것은 내 verify-rm스크립트입니다.

if [ "$#" -lt 2 ];
then
    echo "Bad arguments, use like cp command"
else
    success=0
    fail=0
    error=0
    for arg in ${@:1:$(($#-1))}
    do
        #echo "$arg ${@:(-1):1}"
        diff "$arg" "${@:(-1):1}"
        ret=$?
        if [ $ret -eq 0 ]
        then
            success=$((success+1))
            echo "Verified file $arg"
            rm $arg
        elif [ $ret -eq 1 ]
        then
            fail=$((fail+1))
            echo "Binary files $arg and ${@:(-1):1} differ"
        else
            error=$((error+1))
            echo "diff exited with error: code=$ret"
        fi
    done
    echo "Summary: $success files verified and ok"
    echo "         $fail files differ!"
    echo "         $error errors"
    echo "Files which differ not removed"
    echo "Files where diff returned error code not removed"
fi

스크립트를 실행 가능하게 만들기

$ chmod +x verify-rm

그런 다음 새 스크립트("명령")를 사용합니다.

$ verify-rm /path/to/source/*.jpg /path/to/destination

파일 이름에 공백이 있는 파일은 bash가 공백 사이의 각 문자 집합을 다른 인수로 처리하기 때문에 올바르게 처리되지 않는 것으로 나타났습니다. 무엇을 해야할지, 고칠 수 있는지 모르겠습니다.

rsync --remove-source-files그러나 댓글에는 파일 이름에 공백이 있어도 작동하고 잘 작동한다고 언급되었으며 rsync속도도 훨씬 빠르다는 것을 알았으므로 그냥 사용하는 것이 좋습니다 rsync.

답변2

내 의견을 언급하셨지만 rsync --remove-source-files스크립트 답변을 한 단계 더 발전시키고 싶다면 다음과 같은 몇 가지 팁을 참고하세요.

두 파일(바이너리 파일 포함)에 대해 부울 비교를 수행하려는 경우 표준보다 몇 가지 더 나은 방법이 있습니다 diff. 하나는 cmp두 파일을 바이트 단위로 비교하는 것입니다. 또는 체크섬을 다음과 비교할 수 있습니다.

diff -q <(cksum file1) <(cksum file2)

파일 이름의 공백과 관련하여 이는 여러 가지 해결 방법이 있는 잘 알려진 문제입니다. 다음은 매우 포괄적인 요약입니다.https://www.dwheeler.com/essays/filenames-in-shell.html. 스크립트를 공유할 계획이 없다면 가장 적합한 대안을 선택하세요.

답변3

rsync --remove-source-files당신을 위해 이 정확한 임무를 완수할 것입니다. (그러나 내가 어떻게 해야 할지 몰랐던 한 가지는 대상 파일이 이미 존재하고 일치하는 경우 소스 파일을 삭제하는 것입니다.)

파일의 유효성을 검사하지 않는다는 인상을 받으셨겠지만,맨페이지:

rsync는 파일이 전송될 때 생성된 전체 파일 체크섬을 확인하여 전송된 각 파일이 수신 측에서 올바르게 재구성되었는지 항상 확인하지만 자동 전송 후 확인은 이 옵션과 관련이 없습니다. the-transfer "이 파일을 업데이트해야 합니까?" 보기.

관련 정보