Copie todos los archivos y carpetas, excepto los archivos y carpetas de subversión en OS X


14

Estoy tratando de copiar todos los archivos y carpetas de un directorio a otro, pero excluyo ciertos archivos. Específicamente, quiero excluir archivos y carpetas de subversión. Sin embargo, me gustaría una solución general pero concisa.

Me imagino que encontraré la necesidad de excluir varios tipos de archivos en el futuro cercano. Por ejemplo, podría querer excluir .svn, * .bak y * .prj.

Esto es lo que he reunido, pero no me funciona. La primera parte, buscar trabajos, pero estoy haciendo algo mal con xargs y cp . Intenté cp con y sin el -R. Además, estoy usando OS X y parece tener una versión menos destacada de xargs que los sistemas Linux.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory

Puedo estar equivocado, pero creo que esto es más complicado de lo que piensas. Incluso si su findcomando usa correctamente -prunepara excluir elementos .svn, entonces pasa la -Rbandera a la cpque le dice que ese comando sea recursivo. Cuando lo hace, pierde la granularidad que tenía en el findcomando. Voy a jugar con esto por un minuto, pero creo que la respuesta es no usarlo -Ren el cpcomando.
Telemachus

Parece funcionar para mí en un sistema Linux. ¿Puede ser más específico en cuanto a lo que significa "no funciona"? ¿Algún mensaje de error? ¿Archivos que se copian / no se copian como esperabas?
Pausado hasta nuevo aviso.

Es la -Rbandera, estoy bastante seguro. Quite eso y que debe estar bien (aunque es posible que desee añadir -mindepth 1a ignorar la carpeta directorio principal, que no desea copiar, supongo)
Telémaco

Usualmente hago estas cosas copiando todo y luego borrando los archivos no deseados en los directorios de destino. Eso es a menudo mucho más simple.
Jan Doggen

Respuestas:


22

(Editado después de volver a leer la pregunta. El interlocutor dice que rsync no está instalado)

Un posible problema con su solución find / xargs son los espacios en los nombres de archivo. Para evitar eso, dile a find y xargs que usen un carácter nulo (ASCII 0) para separar los archivos encontrados:

find ./sourcedirectory -not ( -name .svn -a -prune ) -print0 | xargs -0 -IFILES cp FILES ./destinationdirectory

Si encuentra que rsync está disponible, sigo pensando que rsync es la mejor solución:

Use rsync con la opción -C. Desde la página de manual de rsync :

Esta es una abreviatura útil para excluir una amplia gama de archivos que a menudo no desea transferir entre sistemas. Utiliza un algoritmo similar al CVS para determinar si un archivo debe ignorarse.

Esto le dirá a rsync que ignore estos patrones:

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~
#* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj 
*.so *.exe *.Z *.elc *.ln core .svn/ .git/ .bzr/

Por ejemplo:

rsync -avC /path/to/source/directory /path/to/destination/directory

(nota: si aún no está familiarizado con rsync, asegúrese de leer en esa página de manual acerca de cómo rsync trata con una barra inclinada final en la ruta de origen. Se comporta de manera diferente si incluye la barra inclinada que si no lo hace. Buscar 'barra diagonal')


Oh ratas, acabo de releer tu pregunta y vi que dijiste que no tienes instalado rsync. En mi MacBook Pro (OS X 10.6.1) está en / usr / bin / rsync. Fue instalado para mí bajo Tiger (10.4) y Leopard (10.5) también.
Doug Harris

Estoy bastante seguro de que usted (y el OP) no quiere la -Rbandera en la xargsparte del comando.
Telemachus

Buena captura, copié eso de la pregunta original. Se editará ahora.
Doug Harris

1
Gracias Doug! Una cosa que predico es "usar la herramienta adecuada para el trabajo". Recientemente he venido del mundo de Windows a OSX y todavía estoy dando vueltas por ignorancia. Publiqué esta misma pregunta en un canal de Linux y alguien dijo rápidamente: simplemente use "rsynch", escribí "rsynch" en el terminal y vi que no existía y continué investigando el hallazgo | enfoque xargs. Soy un poco terco así. De todos modos, OSX tiene "rsync" por defecto, y su publicación fue muy útil. Todavía no tengo suficiente experiencia para saber cuál es mejor, pero rsync seguro es mucho más conciso. ¡Gracias!
Michael Prescott

Si va a trabajar en máquinas Linux además de su trabajo en OS X, creo que valdrá la pena aprender a usar rsync. Su funcionalidad principal es la copia inteligente de solo las cosas cambiadas (como robocopy en Windows, si está familiarizado con eso). Debido a que copia solo el delta, es una excelente manera de manejar copias de seguridad (no Time Machine), implementaciones de código y similares.
Doug Harris

2

No es una solución general, pero ... puede usar el comando svn export para crear una copia del espacio de trabajo sin las carpetas de metadatos .svn.


No para ser ofensivo, pero no estoy seguro de por qué esta respuesta está siendo votada. Soy consciente de las capacidades de svn, pero "Me gustaría una solución general pero concisa. Creo que encontraré la necesidad de excluir varios tipos de archivos en un futuro próximo"
Michael Prescott

2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

si lo desea, incluso puede poner 'pv' o algo similar entre los 2 procesos tar.


2

Una manera sucia pero rápida y concisa:

cp -r source destination
find destination -iname .svn |xargs rm -rf

Esto copia un directorio a otro (por lo tanto, la opción recursiva -r) y luego borra recursivamente cualquier cosa nombrada .svn(ignorando mayúsculas y minúsculas).


1

Lo haría de una manera diferente, usando tar y su mecanismo de exclusión.

Desde en el directorio de destino:

tar -X excludefile -C source -f - . | tar xf -

Esto creará un cd en la fuente, almacenará el contenido, excluirá lo que se enumera en excludefile y luego lo descomprimirá en el directorio actual.


Solución elegante de hecho.
Nick Stinemates

bueno, es la misma respuesta que di, justo después. además tienes que estar en el directorio de destino ... :)
akira

0

Respuesta editada : El problema es que -Rla copia es recursiva y, por lo tanto, terminas copiando los archivos ocultos. Esto es lo que usaría:

find source/  -mindepth 1 -not \( -name .svn -prune \) | xargs -Iitem cp item target/

La -mindepth 1bandera le dice findque ignore el directorio de nivel superior. Como desea copiar todo el contenido de ese directorio en un nuevo directorio de nivel superior, supongo que no quiere eso.

Como dice Chris Nava en su respuesta , ya hay una forma integrada de hacer esto si hablamos de carpetas SVN, pero dado que solicitó una solución más general, esto puede ayudar un poco.


Gracias Telémaco, es útil. No tengo la experiencia para criticar, pero repetiré lo que me han dicho desde mi publicación original. "Xargs está roto" El comentarista desconocido del IRC que me dijo que me inspiró a mirar un poco más y creo que la respuesta de Doug Harris aborda el problema. Eso le dice a xargs que use caracteres nulos. Creo que ese es el cambio -0?
Michael Prescott

@Michael: xargsno está roto, pero en sistemas tipo Unix, el valor predeterminado es no usar nombres de archivo (o nombres de directorio) con espacios en ellos. Si tiene espacios o caracteres "divertidos" en sus nombres de archivo (o nombres de directorio), entonces debe hacer un trabajo adicional para lidiar con eso. (En GNU find, existe toda una sección en la manpágina llamada "inusuales NOMBRE DE ARCHIVO" debido a este problema.) El -0indicador en xargsy -print0para la findayuda a manejar estos problemas. Sin embargo, te prometo que no quieres usarlo -Ren tu comando de copia. Deshacerá todo lo que haga para evitar los directorios SVN.
Telemachus

0

Supongo que depende de cuán grande sea su árbol, pero ¿por qué no simplemente copie todo primero y luego recorte las carpetas .svn después de:

find /dest-dir -type d -name .svn -exec rm -rf {} \;

?


Sin ninguna evaluación comparativa, mi pensamiento inicial es que este es un doble desperdicio de los ciclos de la CPU: la copia y la eliminación. Puede llevar un poco más de tiempo humano elaborar el findcomando correcto , pero solo lo haces una vez. Puede usar el comando cientos de veces, una vez que lo haga bien.
Telemachus

@Telemachus: es cierto, pero eso es lo que las computadoras son (se supone que son buenas): ¡hacemos las cosas difíciles para que no tengamos que hacerlo! Realmente, ¿qué daño hay al copiar algunos archivos solo para que se eliminen poco después, si eso significa que los comandos que inventas para hacerlo son muy simples?
Steve Folly

@ Steve: no hay daño, de verdad. Hasta donde llega, esta es una buena solución. Sigue un principio que me gusta: "Haz lo más simple posible que funcione". Por otro lado, viola otro principio que me gusta aún más: "Aprende tus herramientas". Preferiría aprender a usarlo findmejor, para no tener que hacerlo. Pero tienes razón: no hay nada realmente malo con esta solución.
Telemachus

@Telemachus: Estoy de acuerdo con "Aprende tus herramientas". Cuando comencé, estoy seguro de que mi comando de búsqueda anterior me habría parecido muy críptico :-)
Steve Folly


0

También puedes hacer lo contrario. Copie todo y luego elimine las carpetas .svn con el siguiente comando:

find . | grep ".svn" | xargs rm -rf
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.