I'm trying to write a script to copy files recursively from a particular folder except files A.extn
, B/*.extn
and C/*
where B
and C
are directories and extn
is just some generic extension. This is what I have:
#!/usr/local/bin/zsh
setopt EXTENDED_GLOB
TMPDIR=/tmp/test
cp -pR $(dirname $0)/**~(*.foo/*|*/bar.txt|*.abc|qux.txt) $TMPDIR
However this doesn't do the negation of the pattern as expected. I think I do know why — although the pattern is correct (as seen with echo
), cp -R
is not aware of the pattern, and enters a directory that it is "not supposed to", and once in there, the pattern is no longer valid.
How do I modify the above to do what I want? I guess it is possible with find
and xargs
, but I'm drawn towards the clarity of the above and would prefer something similar (but if it's the wrong way to do it, I'd be perfectly happy with a different solution).
Best Answer
You are correct that the pattern is expanded before
cp
is run, so is unknown to that command.You may be able to accomplish what you want by using the
--parents
option tocp
rather than-R
. That will only copy the files which match your pattern, but will use the full path name as supplied rather than only the trailing file name.But, this option isn't portable. AFAIK, it's only supported by the GNU version of cp.