
files 을 제외한 특정 폴더에서 파일을 재귀적으로 복사하는 스크립트를 작성하려고 합니다 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입니다. Pax는 또 다른 옵션입니다.
rsync -a --exclude='*.foo/*' --exclude='bar.txt' --exclude='*.abc' --exclude='/qux.txt' $(dirname $0) $TMPDIR