cp를 사용하여 dem 등원으로 폴더를 재귀 적으로 복사하는 방법은 무엇입니까?


46

내가 사용할 때

cp -R inputFolder outputFolder

결과는 상황에 따라 다릅니다 .

  1. outputFolder존재하지 않는 경우 생성되고 복제 된 폴더 경로는입니다 outputFolder.
  2. outputFolder존재하는 경우 생성 된 클론은outputFolder/inputFolder

이 끔찍 좀 설치 스크립트를 만들려고하기 때문에, 사용자가 실수로 두 번 실행하는 경우, 그 것이다 outputFolder모든 물건에 다시 한 번 생성 될 두 번째 실행에 처음 만들어 outputFolder/inputFolder.

  • 나는 항상 첫 번째 행동을 원합니다. 원본 옆에 형제로 복제본을 만듭니다.
  • cp휴대용 으로 사용하고 싶습니다 (예 : MINGW는 rsync배송 되지 않음 )
  • 확인 cp -R --parents했지만 디렉토리 트리까지의 경로를 다시 만듭니다 (복제본은 outputFolder아니지만 some/path/outputFolder)
  • --remove-destination또는 --update2가 아무것도 변경하지 않으면 여전히 내용이 복사됩니다.outputFolder/inputFolder

outputFolder(폴더가 존재하지 않으면 ...) 존재 여부를 먼저 확인 하거나 사용하지 않고이 작업을 수행 할 수 rm -rf outputFolder있습니까?

합의 된 이식 가능한 UNIX 방식은 무엇입니까?



2
이러한 옵션 중 일부는 POSIX가 아니므로 시도한 옵션은 이식성이 떨어집니다. 휴대 성이 부족한 상태로 살 수 있다면 왜 사용하지 rsync않습니까?
muru

1
을 사용할 필요가없는 경우 cptar명령 사이의 파이핑은 트리를 복사하는 데 신뢰할 수있는 좋은 방법입니다.
R ..

@R .. 예제를 제공해 줄 수 있습니까? @muru rsync배송 되지 않은 MINGW에서 작동하고 싶습니다 .
jakub.g

GNU tar로 tar -C input -cf - . | tar -C output -xf -작동합니다. -C작업 디렉토리를 변경하지만 표준 옵션은 아니므로 지원되지 않는 경우 올바른 작업 디렉토리에서 두 개의 tar를 실행해야합니다. 예를 들어 ( cd input && tar -cf - . ) | ( cd output && tar -xf - )Windows를 다루는 경우 roaima의 대답을 사용하십시오.
R ..

답변:


54

대신 이것을 사용하십시오 :

cp -R inputFolder/. outputFolder

이것은 작동하는 것과 똑같은 방식으로 cp -R aaa/bbb ccc작동합니다. ccc존재하지 않으면 사본 bbb과 그 내용 으로 만들어집니다 . 그러나 ccc이미 존재 ccc/bbb하면 사본 bbb과 내용으로 만들어집니다.

거의 모든 경우에 bbb대해 귀하의 질문에 언급 한 바람직하지 않은 행동을 제공합니다. 그러나,이 특정 상황에서이 bbb그냥 ., 그래서 aaa/bbb정말 aaa/.차례로 정말이다, aaa그러나 다른 이름으로. 따라서이 두 가지 시나리오가 있습니다.

  1. ccc 존재하지 않는다:

    명령 cp -R aaa/. ccc수단 "을 만들 ccc및 내용 복사 aaa/.로를 ccc/., 즉 복사 aaaccc.

  2. ccc 존재한다 :

    명령 cp -R aaa/. ccc수단 "의 내용 복사 aaa/.로를 ccc/., 즉 복사 aaaccc.


3
허, 그것은 저에게는 새로운 것이지만 효과가있는 것 같습니다! 이것은 어디서나 문서화 되었습니까?
Ilmari Karonen

1
나는 inputFolder/.대신 테스트를 거쳤 inputFolder으며 실제로 Windows / Git Bash에서 작동합니다. (단지 후행으로 작동하지는 않지만 /슬래시 뒤에 점이 필요합니다). 이 : 너무 까다로운 조금 공공 코드에서 사용하는 아마하지만 나는 그것의 재미 이후 일을했다
jakub.g

@IlmariJaronen 명시 적으로 문서화 할 필요는 없습니다. 설명을 따라 가면 단순히 "규칙을 따르는"방법을 볼 수 있습니다.
roaima

18

폴더를 복사하지 말고 내용 만 복사하십시오.

## Create the target directory. The -p suppresses error messages
## if the directory already exists
mkdir -p outputFolder

## Copy the contents recursively, this will not recreate the parent
cp -R inputfolder/* outputfolder/

이렇게하면 스크립트를 처음 실행할 때 대상 디렉토리가 작성되고 두 번째로 실행할 때 문제를 피할 수 있습니다.

Chris Down은 bash에서 이름이 a로 시작하는 파일을 건너 뜁니다 .. 이를 피하려면 shopt -s dotglob위 명령을 실행 하기 전에 실행할 수 있습니다 .

모두 -p를위한mkdir-R에 대한cp 이 완벽하게 이식해야하므로 POSIX에 의해 정의됩니다.


6
참고 :로 시작하는 파일은 복사되지 않습니다 .. bash에서는 사용할 수 있습니다 dotglob.
Chris Down

2
glob 확장이 최대 명령 행 길이를 초과 할 수 있으므로 입력 폴더의 디렉토리 항목 수가 많으면이 방법이 실패 할 수 있습니다.
Tim Cutts

11

-T옵션을 사용해보십시오 cp. 이것은 GNU coreutils cp버전 8.22에 있습니다. 그 밖에는 휴대 할 수 없습니다.


1
네, 이것이 바로 내가 원하는 것 같습니다 : cp -T( cp --no-target-directory). unix.stackexchange.com/questions/94831/… 불행히도 내 버전 cp은 훨씬 더 오래된 버전입니다 .
jakub.g

1
+1 오늘만 사용했습니다. -u게으른 추가 할 수있는 좋은 옵션입니다.
PSkocik

4

당신은 또한 사용할 수 있습니다 rsync:

rsync -uav inputFolder/ outputFolder/

(특히 첫 번째 슬래시 이후의 슬래시에 유의하십시오)


0

내 의견으로는,보다 단순하고 휴대하기 쉬운 것은 없습니다 rm -rf outputFolder. 그래서 나는 항상 그것을 고수합니다. 귀하의 질문이 다르다는 것을 이해하지만 이것이 최선의 방법이라고 생각합니다.


대상에 유지해야 할 특정 권한이나 소유권이 있으면 실패합니다. 또는 심볼릭 링크 인 경우.
roaima

1
질문은 cp디렉토리가 존재하지 않을 때와 존재 할 때 모두 동일한 결과를 원합니다 . 무슨 소리 야?
dashohoxha

cp영업 이익에 의해 주어진 명령은 권한 (또는 타임 스탬프)를 유지하지 않습니다.
roaima

0

명령 -t옵션을 다음 cp과 같이 사용할 수 있습니다 .

cp -R inputFolder -t outputFolder

이제 대상 폴더가 존재하지 않으면 오류가 발생합니다.

cp: failed to access ‘outputFolder’: No such file or directory

위의 명령은 inputFolder내용뿐만 아니라 내용과 함께 복사 됩니다.

inputFolder별표를 사용하는 동안 쉘 globbing을 사용하는 동안주의해야하기 때문에 내용을 복사 하기가 조금 까다로워집니다.

cp -R  -t outputFolder/ -- inputFolder/*

이제 대상 폴더가 존재하지 않으면 오류가 발생합니다.

cp: failed to access ‘outputFolder’: No such file or directory

와 일하다 cp (GNU coreutils) 8.23

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