Copiez tous les fichiers et dossiers à l'exception des fichiers et dossiers subversion sur OS X

14

J'essaie de copier tous les fichiers et dossiers d'un répertoire à un autre, mais j'exclus certains fichiers. Plus précisément, je souhaite exclure les fichiers et dossiers de subversion. Cependant, j'aimerais une solution générale mais concise.

J'imagine que je trouverai la nécessité d'exclure plusieurs types de fichiers dans un avenir proche. Par exemple, je souhaiterais peut-être exclure .svn, * .bak et * .prj.

Voici ce que j'ai préparé pour, mais cela ne fonctionne pas pour moi. La première partie, trouver des travaux, mais je fais quelque chose de mal avec xargs et cp . J'ai essayé cp avec et sans le -R. En outre, j'utilise OS X et il semble avoir une version moins en vedette de xargs que les systèmes Linux.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory
Michael Prescott
la source
Je me trompe peut-être, mais je pense que c'est plus délicat que vous ne le pensez. Même si votre findcommande utilise correctement -prunepour exclure les éléments .svn, vous passez ensuite l' -Rindicateur cpauquel indique que cette commande est récursive. Dans ce cas, vous perdez la granularité que vous aviez dans la findcommande. Je vais bricoler avec cela pendant une minute, mais je pense que la réponse n'est pas à utiliser -Rdans la cpcommande.
Télémaque le
Cela semble fonctionner pour moi sur un système Linux. Pouvez-vous être plus précis quant à ce que «cela ne fonctionne pas» signifie? Des messages d'erreur? Les fichiers qui sont / ne sont pas copiés que vous attendez?
pause jusqu'à nouvel ordre.
C'est le -Rdrapeau, j'en suis presque sûr. Supprimez cela et ça devrait aller (même si vous voudrez peut-être ajouter -mindepth 1pour ignorer le dossier du répertoire de haut niveau que vous ne voulez pas copier, je suppose)
Telemachus
Je fais généralement ces choses en copiant tout, puis en supprimant les fichiers indésirables dans les répertoires cibles. C'est souvent beaucoup plus simple.
Jan Doggen

Réponses:

22

(Modifié après avoir relu la question. Le répondant dit que rsync n'est pas installé)

Un problème possible avec votre solution find / xargs est les espaces dans les noms de fichiers. Pour contourner cela, dites à find et xargs d'utiliser un caractère nul (ASCII 0) pour séparer les fichiers trouvés:

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

Si vous trouvez que rsync est disponible, je pense toujours que rsync est la meilleure solution:

Utilisez rsync avec l'option -C. Depuis la page de manuel de rsync :

Il s'agit d'un raccourci utile pour exclure une large gamme de fichiers que vous ne souhaitez souvent pas transférer entre les systèmes. Il utilise un algorithme similaire à CVS pour déterminer si un fichier doit être ignoré.

Cela indiquera à rsync d'ignorer ces modèles:

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/

Par exemple:

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

(Remarque: si vous n'êtes pas encore familier avec rsync, assurez-vous de lire sur cette page de manuel comment rsync gère une barre oblique de fin dans le chemin source. Il se comporte différemment si vous incluez la barre oblique que si vous ne le faites pas. Recherche de 'slash de fin')

Doug Harris
la source
Oh rats, je viens de relire votre question et j'ai vu que vous aviez dit que rsync n'était pas installé. Sur mon MacBook Pro (OS X 10.6.1), il se trouve dans / usr / bin / rsync. Il a été installé pour moi sous Tiger (10.4) et Leopard (10.5) également.
Doug Harris
Je suis à peu près sûr que vous (et l'OP) ne voulez pas le -Rdrapeau dans la xargspartie de la commande.
Télémaque le
Bonne capture, je l'ai copié de la question d'origine. Éditera maintenant.
Doug Harris
1
Merci Doug! Une chose que je prêche, "utilisez le bon outil pour le travail". Je suis récemment passé du monde Windows à OSX et je cherche toujours dans l'ignorance. J'ai posté cette même question sur un canal Linux et quelqu'un a rapidement dit, utilisez simplement "rsynch" J'ai tapé "rsynch" dans le terminal et j'ai vu que cela n'existait pas et j'ai continué à enquêter sur la recherche | approche xargs. Je suis un peu têtu comme ça. Quoi qu'il en soit, OSX a "rsync" par défaut, et votre message a été très utile. Je n'ai pas encore assez d'expérience ici pour savoir laquelle est la meilleure, mais rsync est certainement beaucoup plus concis. Merci!
Michael Prescott
Si vous allez travailler avec des machines Linux en plus de votre travail sur OS X, je pense que vous trouverez que cela vaut la peine d'apprendre à utiliser rsync. Sa fonctionnalité principale est la copie intelligente de tout ce qui a changé (comme robocopy sur Windows, si vous êtes familier avec cela). Parce qu'il copie uniquement le delta, c'est un excellent moyen de gérer les sauvegardes (non Time Machine), les déploiements de code et autres.
Doug Harris
2

Pas une solution générale mais ... vous pouvez utiliser la commande d'exportation svn pour créer une copie de l'espace de travail sans les dossiers de métadonnées .svn.

Chris Nava
la source
Ne pas être offensant, mais je ne sais pas pourquoi cette réponse est votée. Je suis au courant des capacités de svn, mais "J'aimerais une solution générale mais concise. J'imagine que je trouverai la nécessité d'exclure plusieurs types de fichiers dans un avenir proche"
Michael Prescott
2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

si vous voulez, vous pouvez même mettre 'pv' ou quelque chose de similaire entre les 2 processus tar.

akira
la source
2

Une manière sale mais rapide et concise:

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

Cela copie un répertoire dans un autre (donc l'option récursive -r) puis efface récursivement tout ce qui est nommé .svn(en ignorant la casse).

michele
la source
1

Je procéderais différemment, en utilisant tar et son mécanisme d'exclusion.

De dans le répertoire de destination:

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

Cela va créer un CD vers la source, tarer le contenu, excluant ce qui est répertorié dans le fichier d'exclusion, puis le décompresser dans le répertoire en cours.

KeithB
la source
Solution élégante en effet.
Nick Stinemates
eh bien, c'est la même réponse que j'ai donnée, juste plus tard. De plus, vous devez être dans le répertoire de destination ... :)
akira
0

Réponse modifiée : Le problème est que -Rvotre copie est récursive et que vous finissez par copier les fichiers cachés. Voici ce que j'utiliserais:

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

Le -mindepth 1drapeau indique findd'ignorer le répertoire de haut niveau. Étant donné que vous souhaitez copier tout le contenu de ce répertoire dans un nouveau répertoire de niveau supérieur, je suppose que vous ne le souhaitez pas.

Comme Chris Nava le dit dans sa réponse , il existe déjà un moyen intégré de le faire si nous parlons de dossiers SVN, mais puisque vous avez demandé une solution plus générale, cela peut aider un peu.

Télémaque
la source
Merci Télémaque, c'est utile. Je n'ai pas l'expérience pour critiquer, mais je vais répéter ce qu'on m'a dit depuis mon post d'origine. "xargs is broken" Le commentateur inconnu de l'irc qui m'a dit qui m'a inspiré à regarder un peu plus et je pense que la réponse de Doug Harris résout le problème. Cela indique à xargs d'utiliser des caractères nuls. Je pense que c'est le commutateur -0?
Michael Prescott,
@Michael: xargsn'est pas cassé, mais sur les systèmes de type Unix, la valeur par défaut n'est pas d'utiliser les noms de fichiers (ou noms de répertoires) avec des espaces dedans. Si vous avez des espaces ou des caractères "drôles" dans vos noms de fichiers (ou noms de répertoire), vous devez faire un travail supplémentaire pour y faire face. (Dans GNU find, il y a une section entière dans la manpage intitulée "FILMS NOMBREUX" à cause de ce problème.) Le -0drapeau dans xargset -print0pour findaider à gérer ces problèmes. Je vous promets, cependant, que vous ne voulez pas utiliser -Rdans votre commande de copie. Il annulera tout ce que vous faites pour éviter les répertoires SVN.
Télémaque le
0

Je suppose que cela dépend de la taille de votre arbre est, mais pourquoi ne pas copier simplement tout d' abord, puis couper les dossiers .svn après:

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

?

Steve Folly
la source
Sans analyse comparative, ma première pensée est que c'est un double gaspillage de cycles CPU: la copie et la suppression. Cela peut prendre un peu plus de temps humain pour créer la bonne findcommande, mais vous ne le faites qu'une seule fois. Vous pouvez utiliser la commande des centaines de fois, une fois que vous avez bien compris.
Télémaque le
@Telemachus - c'est vrai, mais c'est ce que les ordinateurs sont (censés être) bons - faire les trucs délicats pour que nous n'ayons pas à le faire! Vraiment - quel mal y a-t-il à copier certains fichiers pour les supprimer peu de temps après, si cela signifie que les commandes que vous inventez pour le faire sont très simples?
Steve Folly
@Steve: il n'y a vraiment aucun mal. En ce qui concerne cela, c'est une bonne solution. Il suit un principe que j'aime: "Faites la chose la plus simple possible qui fonctionne." Par contre, cela viole un autre principe que j'aime encore plus: "Apprenez vos outils". Je préférerais apprendre à findmieux m'utiliser, pour ne pas avoir à le faire. Mais vous avez raison: il n'y a rien de mal à cette solution.
Télémaque le
@Telemachus: Je suis d'accord avec "Apprenez vos outils". Quand j'ai commencé, je suis sûr que ma commande find ci-dessus m'aurait paru très cryptique :-)
Steve Folly
0

N'oubliez pas grep -v

find . | grep -v .svn
Nick Stinemates
la source
Cette commande ne fait pas ce que vous pensez qu'elle fait.
Juan A. Navarro
0

Vous pouvez également faire le contraire. Copiez tout puis supprimez les dossiers .svn à l'aide de la commande ci-dessous:

find . | grep ".svn" | xargs rm -rf
devXen
la source