Faire un don ! | | style | statistiques | contactez-nous | plan | lettre d'information

Retourner aux forums || Retourner au forum Astuces.divers

Astuces.divers : [Terminal] Exclure un sous-dossier d'une copie recursive

Posté par Jérôme Pinot (page perso, ) le 12 septembre 2005
Objectif :
Vous avez un dossier bien rempli que vous souhaitez dupliquer à un autre endroit à l'exception d'un des sous-dossiers, par exemple parce qu'il est tres volumineux.

Probleme :
Il n'y a pas d'option d'exclusion à la commande "cp" et il peut être fastidieux de devoir copier ou déplacer le sous-dossier en question. Il est parfois necessaire d'avoir une alternative.

Solution :
Soit DIR le dossier a copier, SOUSDIR le dossier a exclure et DESTDIR le dossier qui recevra la copie :

$ cd /chemin/vers/DIR/..
$ find DIR -path '*SOUSDIR*' -prune -o -print -exec cp -r {} DESTDIR/{} \;


Ainsi, vous ne copiez qu'une seule fois les fichiers.

Il est egalement possible d'utiliser "tar" qui possede une option d'exclusion (merci daemoOon<) mais qui oblige globalement à copier 2 fois "DIR-SOUSDIR" ce qui peut être long en fonction des données.

Merci aussi à zragg< qui m'a mis sur la voie.

> Lire le message (4 commentaires, moyenne: 1,3).  

Cette discussion est archivée, il n'est plus possible de laisser des commentaires.

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.

Une seule fois ???

Posté par Arthur Accroc () le 11/11/2005 à 13:22. (lien). Évalué à 1.

Ainsi, vous ne copiez qu'une seule fois les fichiers.

Alors là, j'ai un gros doute...
find parcoure toute l'arborescence et cp -r fait des copies récursives...

Allez hop, un petit test, en ajoutant un echo dans le -exec pour juste voir les commandes qui seraient effectuées :
find testdir -path testdir/B -prune -o -exec echo cp -r {} testdest/{} \;
cp -r testdir testdest/testdir
cp -r testdir/C testdest/testdir/C
cp -r testdir/C/a testdest/testdir/C/a
cp -r testdir/A testdest/testdir/A
cp -r testdir/A/b testdest/testdir/A/b
cp -r testdir/A/a testdest/testdir/A/a
cp -r testdir/A/A testdest/testdir/A/A
cp -r testdir/A/A/a testdest/testdir/A/A/a


cp -r (récursif) testdir testdest/testdir copie tout le répertoite testdir, puis cp -r testdir/C testdest/testdir/C copie à nouveau le répertoire testdir/C...
Plutôt mortel sur un gros répertoire avec unr arborescence profonde !
Qui plus est, cp -r testdir testdest/testdir va avoir copié le répertoire testdir/B dans la foulée...

La suppression du -r poserait des problèmes avec les répertoires (cp ne copierait pas les répertoires et la tentative de copie dans un répertoire inexistant causerait une erreur).

L'utisation des options -mindepth et -maxdepth permettrait de s'en sortir, pourvu que le sous-répertoire à ne pas copier soit à la base :
$ find testdir -mindepth 1 -maxdepth 1 -path testdir/B -prune -o -exec echo cp -a {} testdest/{} \;
cp -a testdir/C testdest/testdir/C
cp -a testdir/A testdest/testdir/A

Et encore faudrait-il avoir créé le répertoire testdest/testdir avant.

Il est egalement possible d'utiliser "tar" qui possede une option d'exclusion (merci daemoOon<) mais qui oblige globalement à copier 2 fois "DIR-SOUSDIR" ce qui peut être long en fonction des données.

C'est plutôt le reste qu'on copierait deux fois, mais on peut s'en sortir en passant par les sortie et entrée standard :
$ tar cpf - --exclude B testdir | tar xpvf - -C testdest
testdir/
testdir/C/
testdir/C/a
testdir/A/
testdir/A/b
testdir/A/a
testdir/A/A/
testdir/A/A/a


Qui plus est, dans ce cas, on peut tout-à-fait exclure un répertoire situé plus profondément dans l'arborescence :
$ tar cpf - --exclude A/A testdir | tar xpvf - -C testdest
testdir/
testdir/C/
testdir/C/a
testdir/B/
testdir/B/a
testdir/A/
testdir/A/b
testdir/A/a


tar est ton ami. | aussi.

--
"Casse-toi, alors, pauv' con !"
Nicolas S., grand homme d'état. Ou pas.
  • [^]Re: Une seule fois ???

    Posté par Jérôme Pinot (page perso, ) le 31/12/2005 à 03:47. (lien). Évalué à 1.

    Allez hop, un petit test, en ajoutant un echo dans le -exec pour juste voir les commandes qui seraient effectuées :

    Ce n'est pas parce que des commandes sont passes au shell qu'elles ont forcement une action effective. Je te conseille d'utiliser l'option -v de cp qui te montrera exactement ce qu'il fait.

    cp -r (récursif) testdir testdest/testdir copie tout le répertoite testdir, puis cp -r testdir/C testdest/testdir/C copie à nouveau le répertoire testdir/C...
    Plutôt mortel sur un gros répertoire avec unr arborescence profonde !
    Qui plus est, cp -r testdir testdest/testdir va avoir copié le répertoire testdir/B dans la foulée...


    Non. Je voudrais bien que tu m'expliques comment cp peut se permettre d'ecraser des fichiers sans qu'on lui demande explicitement via l'option -f. Fais le test, tu veras que les fichiers ne sont pas ecrases, et donc copies une seule fois, meme les timestamps ne changent pas d'ailleurs.

    La suppression du -r poserait des problèmes avec les répertoires (cp ne copierait pas les répertoires et la tentative de copie dans un répertoire inexistant causerait une erreur).

    En fait, un -R ou un -a serait plus judicieux, mais ca ne change pas le principe.

    C'est plutôt le reste qu'on copierait deux fois

    Comment ca ?

    tar cpf - --exclude B testdir | tar xpvf - -C testdest

    Ca, ca marche \o/

rsync

Posté par KiKouN (Jabber id, ) le 08/05/2006 à 08:07. (lien). Évalué à 2.

Utiliser rsync avec l'option --exclude-dir.

--
KiKouN, Bucheron-Geek

une autre piste avec find...

Posté par xylo (page perso, ) le 10/04/2008 à 19:11. (lien). Évalué à 1.

Objectif:
Copier l'ensemble des fichiers et des dossiers d'un directory en excluant le dossier exclud_dir

1) se placer dans le dossier qui contient les sources
2) pour test avec la fonction echo:
find . \( ! -name "exclud_dir" \) -exec echo {} \;

3) remplacer la fonction echo par la fonction cp

--
'Content de peu n'a rien à craindre'
http://jm.marino.free.fr

Revenir en haut de page || Retourner aux forums || Retourner au forum Astuces.divers