Modificando los patrones globales de zsh para usarlos con cp

Modificando los patrones globales de zsh para usarlos con cp

Estoy intentando escribir un script para copiar archivos de forma recursiva desde una carpeta en particular, excepto archivos A.extn, B/*.extny C/*donde Bestán Clos directorios y extnes solo una extensión genérica. Esto es lo que tengo:

#!/usr/local/bin/zsh
setopt EXTENDED_GLOB
TMPDIR=/tmp/test

cp -pR $(dirname $0)/**~(*.foo/*|*/bar.txt|*.abc|qux.txt) $TMPDIR

Sin embargo, esto no niega el patrón como se esperaba. Creo que sé por qué: aunque el patrón es correcto (como se ve con echo), cp -Rno es consciente del patrón e ingresa a un directorio que "se supone que no debe", y una vez allí, el patrón ya no es válido.

¿Cómo modifico lo anterior para hacer lo que quiero? Supongo que es posible con findy xargs, pero me atrae la claridad de lo anterior y preferiría algo similar (pero si es la forma incorrecta de hacerlo, estaría perfectamente feliz con una solución diferente).

Respuesta1

Tiene razón en que el patrón se expande antes de cpejecutarse, por lo que ese comando lo desconoce.

Es posible que pueda lograr lo que desea utilizando la --parentsopción en cplugar de -R. Eso solo copiará los archivos que coincidan con su patrón, pero usará el nombre de ruta completo tal como se proporciona en lugar de solo el nombre del archivo final.

Pero esta opción no es portátil. AFAIK, solo es compatible con la versión GNU de cp.

Respuesta2

Su patrón puede excluir los archivos que no desea copiar, pero no excluye los directorios que los contienen y le indicó cpque copiara de forma recursiva. Entonces los archivos se copian de todos modos. Peor que eso, si tienes un árbol fuente como

foo
foo/bar.txt
hello
hello/world
hello/world/wibble.txt

luego el patrón se expande para foo hello hello/world hello/world/wibble.txtque termines con estos archivos en $TMPDIR:

foo
foo/bar.txt
hello
hello/world
hello/world/wibble.txt
wibble.txt
world
world/wibble.txt

Esto no tiene nada que ver con que el patrón "ya no sea válido". El patrón se expande mediante el shell, cpsolo ve la lista de archivos.

Debe utilizar una herramienta de copia que pueda excluir archivos mientras realiza el recorrido recursivo.

Puede usar zcp para eso, pero no copiará los directorios y no creará directorios de destino automáticamente. La herramienta más sencilla para este trabajo es rsync. Pax es otra opción.

rsync -a --exclude='*.foo/*' --exclude='bar.txt' --exclude='*.abc' --exclude='/qux.txt' $(dirname $0) $TMPDIR

información relacionada