파일이 아닌 특정 폴더에서 파일을 재귀적으로 복사하는 스크립트를 작성하려고 합니다. A.extn
은 B/*.extn
디렉토리이고 일부 일반적인 확장자입니다. 이것이 내가 가진 것입니다:C/*
B
C
extn
#!/usr/local/bin/zsh
setopt EXTENDED_GLOB
TMPDIR=/tmp/test
cp -pR $(dirname $0)/**~(*.foo/*|*/bar.txt|*.abc|qux.txt) $TMPDIR
그러나 예상대로 패턴이 부정되지는 않습니다. 나는 그 이유를 알고 있다고 생각합니다. 비록 모드가 정확하더라도(표시된 것처럼 echo
), cp -R
모드를 알지 못하고 "해서는 안 되는" 디렉토리에 들어가고 해당 디렉토리에 들어가면 모드가 더 이상 작동하지 않습니다.
원하는 효과를 얻으려면 위의 내용을 어떻게 수정해야 합니까? 나는 find
그것이 가능하다고 생각 xargs
하지만 위의 명확성에 매력을 느끼고 비슷한 것을 선호합니다(그러나 이것이 잘못된 접근 방식이라면 다른 솔루션에 매우 만족할 것입니다).
답변1
맞습니다. cp
실행하기 전에 모드가 확장되므로 명령을 알 수 없습니다.
대신 --parents
에 옵션을 사용하여 원하는 것을 달성할 수 있습니다 . 이는 패턴과 일치하는 파일만 복사하지만 후행 파일 이름뿐만 아니라 제공된 전체 경로 이름을 사용합니다.cp
-R
그러나 이 옵션은 이식 가능하지 않습니다. AFAIK, GNU 버전의 cp만 지원합니다.
답변2
패턴은 복사하고 싶지 않은 파일을 제외할 수 있지만 해당 파일이 포함된 디렉터리는 제외하지 않으며 cp
반복적으로 복사하도록 지시합니다. 따라서 파일은 어쨌든 복사됩니다. 이보다 더 나쁜 것은 이와 같은 소스 트리가 있는 경우입니다.
foo
foo/bar.txt
hello
hello/world
hello/world/wibble.txt
그런 다음 패턴이 확장되어 foo hello hello/world hello/world/wibble.txt
다음 파일이 생성됩니다 $TMPDIR
.
foo
foo/bar.txt
hello
hello/world
hello/world/wibble.txt
wibble.txt
world
world/wibble.txt
이는 "더 이상 유효하지 않음" 패턴과 관련이 없습니다. 이 모드는 셸에 의해 확장되며 cp
파일 목록만 표시됩니다.
재귀 순회를 수행하는 동안 파일을 제외할 수 있는 복사 도구를 사용해야 합니다.
이 목적으로 zcp를 사용할 수 있지만 디렉터리를 복사하지도 않고 대상 디렉터리를 자동으로 생성하지도 않습니다. 이 작업을 위한 가장 간단한 도구는 rsync입니다. 공원은 또 다른 옵션입니다.
rsync -a --exclude='*.foo/*' --exclude='bar.txt' --exclude='*.abc' --exclude='/qux.txt' $(dirname $0) $TMPDIR