Linux에서 동일한 파일 시스템의 두 디렉토리를 병합하는 가장 좋은 방법은 무엇입니까?

Linux에서 동일한 파일 시스템의 두 디렉토리를 병합하는 가장 좋은 방법은 무엇입니까?

함께 병합해야 하는 두 개의 디렉토리가 있습니다. 이 두 디렉터리에 있는 파일은 모두 대용량 파일(>= 500MB)입니다.

아카이브하고 싶은 것: 소스 디렉토리에 있는 파일의 경우: 대상 디렉토리에 없으면 mv대상 디렉토리로 이동합니다(기본적으로 새 하드 링크를 생성하고 소스 파일의 링크를 해제하므로 빠릅니다). 대상 디렉토리에 소스 파일이 있으면 거기에 소스 파일을 복사하고 소스 파일을 제거하십시오.

Linux 시스템에서 디렉토리를 병합하는 가장 일반적인 방법은 옵션 rsync과 함께 사용하는 것입니다 --remove-source-files. 하지만 대상 파일이 없어도 복사 작업을 수행하므로 속도가 느립니다.

더 좋은 아이디어가 있나요? 감사합니다.

답변1

기본적으로 설명하신 내용은 파일이 존재하는 경우 덮어쓰기 대상으로 이동하는 것입니다. 그러니 그냥 옮기세요.

답변2

실패 하는 경우도 있습니다 mv. 다음은 몇 가지 예시 데이터입니다.

mkdir -p src/d dest/d
touch src/d/f1 dest/d/f2

실패 사례를 확인하세요 mv.

$ mv src/* dest/
mv: cannot move 'src/d' to 'dest/d': Directory not empty
$ mv -f src/* dest/
mv: cannot move 'src/d' to 'dest/d': Directory not empty
$ mv -fv src/* dest/
mv: cannot move 'src/d' to 'dest/d': Directory not empty
$ mv -fvi src/* dest/
mv: overwrite 'dest/d'? y
mv: cannot move 'src/d' to 'dest/d': Directory not empty
$ mv -fvi -t dest/ src/*      
mv: overwrite 'dest/d'? y
mv: cannot move 'src/d' to 'dest/d': Directory not empty

따라서 스크립트 파일을 만드십시오.

vim supermove

이 예에서는 오류 검사를 수행하지 않으며(면책 조항: 저에게는 작동하지만, 작동하는지 테스트해 보십시오... 아마도 echobefore 와 함께 mv) 동일한 경로의 파일을 덮어씁니다. 그리고 매우 비효율적인 find를 사용 \;하지만 앞에 추가된 기능 +은 제대로 작동하지 않습니다 "$dest". 이전 버전에서는 경로가 추가되지 않은 일부 디렉토리를 만들고 최신 버전의 find에서는 다음과 같이 표시됩니다.

find: In '-exec ... {} +' the '{}' must appear by itself, but you specified 'dest/{}'

그래도 xargs를 사용하여 문제를 해결할 수 있는 방법을 찾을 수 있을 것입니다. (이동 중이던 64k 파일 8TB에서 몇 분이 걸렸습니다.) 다음 콘텐츠를 추가하세요.

#!/bin/bash

src=$1
dest=$2

src=$(readlink -f "$src")
dest=$(readlink -f "$dest")

cd "$src"

# also copy hidden files
shopt -s dotglob

# make dirs (missing old permission,acl,xattr data), and then mv the files
time find * -type d -exec mkdir -p "$dest"/{} \;
time find * -type f -exec mv {} "$dest"/{} \;

# also copy permissions, acls, xattrs
rsync -aAX "$src"/ "$dest"/

그리고 실행 가능하게 만드세요:

chmod +rx supermove

그리고 실행해 보세요

./supermove src/ dest/

그리고 그 결과는... 이전:

$ find src dest
src/
src/d
src/d/f1
dest/
dest/d
dest/d/f2

후에:

$ find src dest
src
src/d
dest
dest/d
dest/d/f1
dest/d/f2

이제 src/빈 디렉토리여야 합니다. 그렇다면 rm -r src청소할 수 있습니다.

답변3

mv옵션은 모두 충돌 해결에 관한 것입니다.

하나를 선택:

-f  force (always overwrite)
-i  interactive (ask whether to overwrite)
-n  no clobber (no overwrite)

그리고 이것도 좋습니다:

-v  verbose

그렇지 않으면 데이터가 손실되거나 정확히 무슨 일이 일어났는지 명확하지 않을 수 있습니다.

mv는 디렉토리 inode를 업데이트하는 것이므로 동일한 fs에서도 우수합니다. 파일이 엉망이되어서는 안됩니다. 또 다른 점은 작업이 클수록 소프트 오류와 같은 문제가 발생할 가능성이 더 크다는 것입니다.

관련 정보