mv로 대상 파일을 덮어 쓰는 방법은 무엇입니까?


154

부모 디렉토리로 이동하려는 하위 디렉토리에 많은 파일과 디렉토리가 있습니다. 대상 디렉토리에 덮어 써야 할 파일과 디렉토리가 이미 있습니다. 대상에만있는 파일은 그대로 두어야합니다. 강제 mv로 할 수 있습니까? mv * ..불만 ( )

mv: cannot move `xyz' to `../xyz': Directory not empty

내가 무엇을 놓치고 있습니까?


3
당신은 시도 했습니까 mv -f?
sakisk

mv -f정답이 아닌지 궁금 합니다.
Pedro Lobito

@PedroLobito : 작동하지 않기 때문에? -f는 파일을 덮어 쓰지만 대상에 존재하고 비어 있지 않은 하위 디렉토리를 이동하면 작동하지 않습니다.
EricSchaefer

답변:


117

당신은 명령을 사용하여 소스를 대상으로 복사 한 후 삭제해야합니다 cp -r * ..다음을 rm -rf *.

나는 당신이를 사용하여 디렉토리를 "병합"할 수 없다고 생각합니다 mv.


4
글쎄, 내가하고 싶지 않은 일인데, 시간이 오래 걸리기 때문이다. 어쨌든 고마워.
EricSchaefer

12
아마도 mv같은 파일 시스템에 있기 때문에 더 빠를까요? cp -l실제로 파일을 이동하지 않고 하드 링크를 만드는 데 사용 하는 경우 어떻게 됩니까?
mattdm

6
파일 속성 (타임 스탬프, 권한 등)을 유지 하려면 cp -a대신 사용해야합니다 cp -r.
dotancohen

2
Google을 통해 늦게 도착하는 사람들의 경우 @palswim의 아래 답변은 데이터에 대한 새로운 하드 링크를 만든 다음 이전 링크를 삭제하여 mv의 동작을 에뮬레이트합니다. 짧은 대답 cp -rl source destination && rm -r source.
윌리엄 에버렛

72

rsync아마도 더 나은 옵션 일 것입니다. 간단합니다 rsync -a subdir/ ./.

내 테스트 트리 filename: contents형식 :

./file1:root
./file2:root
./dir/file3:dir
./dir/file4:dir
./subdir/dir/file3:subdir
./subdir/file1:subdir

달리기 rsync:

$ rsync -a -v subdir/ ./
sending incremental file list
./
file1
dir/
dir/file3

제공합니다 :

./file1:subdir
./file2:root
./dir/file3:subdir
./dir/file4:dir
./subdir/dir/file3:subdir
./subdir/file1:subdir

그런 다음 에뮬레이션 mv하려면 소스 디렉토리를 제거하고 싶을 것입니다.

$ rm -r subdir/

기부:

./file1:subdir
./file2:parent
./dir/file3:subdir
./dir/file4:dir

이것이 틀렸다면, 원하는 결과를 가진 유사한 예제를 제공 할 수 있습니까 (예 :이 답변의 상단 근처에서 테스트 트리 사용)?


1
rsync 사본. 이 질문은 이사에 관한 것입니다.
Gilles

1
@Gilles : 감사합니다. rm -r끝에 기본적으로와 동일하게 추가 했습니다 mv.
Mikel

3
copy-then-delete는 소스와 대상이 동일한 파일 시스템에있을 때 mv와 동일하지 않습니다. mv은 원자 적이며 inode 번호를 유지하므로 파일을 열어 둘 수 있으며 시간과 공간이 걸리지 않습니다.
Gilles

5
@ Giles : 나는 그것을 알고 있지만 현재 최고의 대답은 cp -r; rm -r입니다. 그런 의미에서 rsync언급 할 가치가 있다고 생각 합니다.
Mikel

나는 이미 cp / rm을 사용하여 그것을했다. 정말 오랜 시간이 걸렸습니다. Gilles 스크립트는 아마도 훨씬 빠르 겠지만 너무 늦었습니다.
EricSchaefer

47

rsync--remove-source-files매개 변수를 사용하여 복사 한 후 소스를 삭제할 수 있습니다 . 이것은 원하는 것을 할 수있는 편리한 방법이어야합니다.

에서 rsync man page:

        --remove-source-files   sender removes synchronized files (non-dir)

이것이 실제로 가장 좋은 대답입니다. cp -r; rm여유 공간이 없어서 사용할 수 없었습니다 . 대신 rsync --remove-source-files사용 된 디스크 공간을 최소화하여 정확히 동일한 파일을 복사하지 않았습니다.
guaka

20

cp및 로이 작업을 수행 할 수 rm있지만 방대한 양의 데이터를 복사하지 않고도 전송을 피하려고합니다. @mattdm는이 언급 자신의 의견다른 질문에 대한 대답은 다양한 옵션에 대한 대한 자세한 설명이 있습니다.

cp -rlf source destination
rm -r source

기본적으로이 명령 -l옵션은 cp데이터를 새 파일로 복사하지 않고 파일에 대한 하드 링크를 만듭니다.


1
나는 알고 영업 이익은 이미 자신의 작업을 완료 질문을하라는 메시지가, 그러나 희망이 대답은 앞으로이 문제를 사람을 도울 수 있습니다.
palswim

이것이 실제로 필요한 답변입니다. 방금 60GB의 작은 사이러스 전자 메일 파일로이 작업을 수행했으며 21 초 밖에 걸리지 않았습니다.
labradort

이것은 또한 내가 선택한 경로입니다. 방금 cp -al source destination소유자 정보와 권한을 유지 하기 위해 변경했습니다 .
piit79

OP가 -f 옵션을 추가해야한다고 요청한 것을 실제로 수행한다고 생각합니다. 그렇지 않으면 파일이 존재하면 덮어 쓰지 않습니다. 그 사실을 확인할 수 있습니까, 아니면 내가 잘못하고 있습니까?
das Keks

@dasKeks : 실제로 cp기본적으로 덮어 씁니다. 이 -f옵션은 파일 rm을 새로 복사하기 전에 (와 같이 ) 파일을 제거하려고 시도 합니다. 프로세스에서 파일을 쓰기 위해 파일을 열 수없는 경우 도움이 될 수 있지만 일부 사람들은 대신 오류가있는 것을 선호합니다. OP에 중요한지 모르겠지만 -f어쨌든 내 대답에 플래그를 추가했습니다 .
palswim

8

아래 /path/to/source/root에서 파일을 아래 의 해당 경로로 이동하는 스크립트가 있습니다 /path/to/destination/root.

  • 소스와 대상 모두에 디렉토리가 있으면 내용이 반복적으로 이동 및 병합됩니다.
  • 파일이나 디렉토리가 소스에는 있지만 대상에는없는 경우 이동됩니다.
  • 대상에 이미 존재하는 모든 파일 또는 디렉토리는 남아 있습니다. (특히 병합 된 디렉토리는 소스에 남아 있습니다. 이는 수정하기 쉽지 않습니다.)

테스트되지 않은 코드를 조심하십시오.

export dest='/path/to/destination/root'
cd /path/to/source/root
find . -type d \( -exec sh -c '[ -d "$dest/$0" ]' \; -o \
                  -exec sh -c 'mv "$0" "$dest/$0"' {} \; -prune \) \
    -o -exec sh -c '
        if ! [ -e "$dest/$0" ]; then
          mv -f "$0" "$dest/$0"
        fi
' {} \;

두 가지 수정 사항 : 명령 의 첫 번째 줄에서 \;이전 이 필요하며 이스케이프해서는 안됩니다 . – 그냥-ofind!if!\!
llhuii

2

이 스레드는 몇 년 동안 존재했지만 여전히 Google에서 1 위를 차지하므로 다른 방법을 추가하고 싶었습니다. 내가 일반적으로하는 방법 : 하위 디렉토리 내용을 tarball로 압축하고 tarball을 상위 디렉토리로 이동시킨 다음 기본 --overwrite 동작으로 추출하십시오. 이것은 당신이 찾고있는 것을 정확하게 수행합니다. 이후에 하위 디렉토리를 제거 할 수 있습니다.

cd xyz
tar -cvzpf tmp.tar.gz *
mv tmp.tar.gz ../tmp.tar.gz
cd ..
tar -xvzpf tmp.tar.gz
rm -rf xyz
rm -f tmp.tar.gz

압축 된 tar 파일을위한 추가 공간이있는 경우에만 작동합니다. 그리고 추출 후 임시 tar 파일을 유지하고 싶습니까?
Anthon

tmp 파일을 제거하도록 코드를 편집했습니다. 오늘날 공간은 대부분의 경우 문제가되지 않습니다. #terabyteages
사이먼 크라우스

0

저장 공간이 충분하면 다음과 같은 방법으로 수행 할 수 있습니다.

mv -bfv directory_1/* directory_2/ # all duplicate source files/directories 
                                   # will have ~ appended to them
find -name "*~" -delete            # will recursively find and delete all files 
                                   # with ~ on the end

끝에 ~가있는 중요한 파일이 없는지 확인하십시오. 파일이 있으면 --suffix=whateveryouwant기본값 대신 추가 할 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.