Copier la structure des dossiers (sans fichiers) d'un emplacement à un autre

94

Je souhaite créer un clone de la structure de notre serveur de fichiers de plusieurs téraoctets. Je sais que cp --parents peut déplacer un fichier et sa structure parent, mais existe-t-il un moyen de copier la structure de répertoire intacte?

Je veux copier sur un système Linux et notre serveur de fichiers est monté sur CIFS.

r00fus
la source
1
Possible duplication de Rsync comment inclure des répertoires mais pas des fichiers?
Trevor Boyd Smith
La solution rsync du commentaire ci-dessus semble plus soignée.
YE du

Réponses:

158

Vous pouvez faire quelque chose comme:

find . -type d > dirs.txt

pour créer la liste des répertoires, puis

xargs mkdir -p < dirs.txt

pour créer les répertoires sur la destination.

Greg Hewgill
la source
8
Cette solution ne fonctionnera pas si vous avez des espaces dans vos noms de répertoire.
Jealie
29
@Jealie Remplacez les commandes par find . -type d -print0 >dirs.txtet xargs -0 mkdir -p <dirs.txt. Cela amènera les deux commandes à utiliser des valeurs nulles comme séparateurs au lieu d'espaces.
user1207177
3
xargspeut dépasser la longueur de commande maximale du système lorsque vous commencez à traiter des commandes de centaines ou de milliers, alors utilisez-le avec prudence. (Trouvez la limite de longueur de commande avec getconf ARG_MAX.) Avec beaucoup de répertoires, vous devrez peut-être écrire un script pour parcourir la sortie à la place.
palswim
1
Et qu'en est-il des autorisations et des attributs seront-ils conservés?
Ashish Karpe
3
@TrevorBoydSmith: Merci pour votre commentaire. La question d'origine ne mentionnait rien sur la nécessité de préserver les autorisations, la propriété ou les attributs. Cela nécessiterait une solution différente, comme vous le mentionnez, mais ce qui précède est suffisant pour répondre à la question posée.
Greg Hewgill
79
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
amphétamachine
la source
3
Meilleure réponse de ma part avec trouver. Sinon, vous pouvez essayer la rsyncsolution de la réponse de Chen Levy dans cette question SO
Mat M
3
Qu'est-ce que l'option - mkdir?
Bruce_Warrior
9
--est un terminateur d'option d'utilitaire GNU standard. Cela signifie "hé mkdir, tout argument après ceci, ce n'est pas un drapeau, alors traitez-le comme un argument de fichier, même s'il commence par un caractère '-'."
amphétamachine
4
cette réponse ne conserve pas non plus les autorisations et les attributs du répertoire . Utilisez rynsc pour préserver les autorisations et les attributs
Trevor Boyd Smith
35

Voici une solution simple utilisant rsync:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • une ligne
  • aucun problème avec les espaces
  • conserver les autorisations

J'ai trouvé cette solution là-bas

Gildas
la source
10
idem mais plus lisiblersync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain
1
Le problème avec cette solution est le suivant: mes dossiers contiennent des milliers de fichiers et rsync prend du temps pour synchroniser une douzaine de dossiers.
Christopher K.
6

Je ne sais pas si vous cherchez une solution sous Linux. Si c'est le cas, vous pouvez essayer ceci:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
zérodine
la source
cpio ne semble pas fonctionner pour moi, du moins avec les paramètres que vous avez spécifiés.
r00fus
@ r00fus - veuillez lire le manuel de cpio ou consulter gnu.org/software/cpio
zerodin
6

Ceci copie les répertoires et les attributs des fichiers, mais pas les données des fichiers:

cp -R --attributes-only SOURCE DEST

Ensuite, vous pouvez supprimer les attributs des fichiers si cela ne vous intéresse pas:

find DEST -type f -exec rm {} \;
toliveira
la source
1
Ce serait excellent, mais vous avez oublié de mentionner la sauvegarde de la propriété, de l'horodatage et des autorisations. Cela a donc produit un désordre dans Win7 / cygwin - utilisateur NULL_SID, mauvais ordre des autorisations, ne peut pas modifier les autorisations, etc. et ne peut pas accéder à la structure de fichiers produite.
WebComer
1
Je devrais penser que le blâme incombe carrément à quiconque essaie d'utiliser Windows pour un vrai travail.
tripleee
cp -R --attributes-only --preserve = all --parents -v SOURCE DEST
Gábor
2

La solution suivante a bien fonctionné pour moi dans divers environnements:

sourceDir="some/directory"
targetDir="any/other/directory"

find "$sourceDir" -type d | sed -e "s?$sourceDir?$targetDir?" | xargs mkdir -p
yaccob
la source
2

Cela marche:

find ./<SOURCE_DIR>/ -type d | sed 's/\.\/<SOURCE_DIR>//g' | xargs -I {} mkdir -p <DEST_DIR>"/{}"

Remplacez simplement SOURCE_DIR et DEST_DIR.

mijhael3000
la source
2

Cela résout même le problème des espaces blancs:

Dans le répertoire d'origine / source:

find . -type d -exec echo "'{}'" \; > dirs2.txt

puis recréez-le dans le répertoire nouvellement créé:

mkdir -p <../<SOURCEDIR>/dirs2.txt
Thim
la source
1

Remplacez target_diret source_diravec les valeurs appropriées:

cd target_dir && (cd source_dir; find . -type d ! -name .) | xargs -i mkdir -p "{}"

Testé sur OSX + Ubuntu.

Luissquall
la source
0

Un script python de Sergiy Kolodyazhnyy publié sur Copier uniquement les dossiers et non les fichiers? :

#!/usr/bin/env python
import os,sys
dirs=[ r for r,s,f in os.walk(".") if r != "."]
for i in dirs:
    os.makedirs(os.path.join(sys.argv[1],i)) 

ou de la coque:

python -c 'import os,sys;dirs=[ r for r,s,f in os.walk(".") if r != "."];[os.makedirs(os.path.join(sys.argv[1],i)) for i in dirs]' ~/new_destination

FYI:

Franck Dernoncourt
la source
0

Une autre approche consiste à utiliser le treequi est assez pratique et à naviguer dans les arborescences de répertoires en fonction de ses options fortes. Il existe des options pour le répertoire uniquement, exclure les répertoires vides, exclure les noms avec motif, inclure uniquement les noms avec motif, etc.man tree

Avantage : vous pouvez éditer ou revoir la liste, ou si vous faites beaucoup de scripts et créez fréquemment un lot de répertoires vides

Approche : créez une liste de répertoires en utilisant tree, utilisez cette liste comme entrée d'arguments pourmkdir

tree -dfi --noreport > some_dir_file.txt

-dfi liste uniquement les répertoires, imprime le chemin complet de chaque nom, empêche l'arborescence d'imprimer les lignes d'indentation,

--noreport Omet l'impression du rapport de fichier et de répertoire à la fin de la liste de l'arborescence, juste pour que le fichier de sortie ne contienne pas de peluches

Ensuite, allez à la destination où vous voulez les répertoires vides et exécutez

xargs mkdir < some_dir_file.txt
frère-bilo
la source
0
find source/ -type f  | rsync -a --exclude-from - source/ target/

Copier le répertoire uniquement avec l'autorisation et la propriété associées

Peng tigre
la source
0

Solution 1 ligne:

find . -type d -exec mkdir -p /path/to/copy/directory/tree/{} \;
Igor
la source
-1

Si vous pouvez accéder à partir d'une machine Windows, vous pouvez utiliser xcopy avec / T et / E pour copier uniquement la structure des dossiers (le / E inclut les dossiers vides)

http://ss64.com/nt/xcopy.html

[ÉDITER!]

Celui-ci utilise rsync pour recréer la structure des répertoires mais sans les fichiers. http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

Ça pourrait être mieux :)

dotalchemy
la source
1
Malheureusement, notre serveur de fichiers CIFS ne fonctionne pas sous Windows, donc personne ne peut le faire avec les commandes win.
r00fus
Merci, la méthode rsync a parfaitement fonctionné pour moi. Il est également compatible avec les espaces dans les noms de répertoire.
Glutanimate
-1

Voici une solution en php qui:

  • copie les répertoires (non récursivement, un seul niveau)
  • préserve les autorisations
  • contrairement à la solution rsync, est rapide même avec des répertoires contenant des milliers de fichiers car elle ne va même pas dans les dossiers
  • n'a aucun problème avec les espaces
  • devrait être facile à lire et à régler

Créez un fichier comme syncDirs.phpavec ce contenu:

<?php
foreach (new DirectoryIterator($argv[1]) as $f) {
    if($f->isDot() || !$f->isDir()) continue;
        mkdir($argv[2].'/'.$f->getFilename(), $f->getPerms());
        chown($argv[2].'/'.$f->getFilename(), $f->getOwner());
        chgrp($argv[2].'/'.$f->getFilename(), $f->getGroup());
}

Exécutez-le en tant qu'utilisateur disposant de suffisamment de droits:

sudo php syncDirs.php /var/source /var/destination

Christopher K.
la source
Vous n'êtes pas obligé d'aimer PHP et vous n'êtes pas obligé de l'utiliser. Mais l'OP n'a pas précisé s'il voulait une solution dans un langage spécifique et, que vous le vouliez ou non, PHP est installé de toute façon sur de nombreux systèmes Linux car 80% du Web utilise PHP ( w3techs.com/technologies/details/pl- php / tous / tous ).
Christopher K.