Kopieren Sie die Ordnerstruktur (ohne Dateien) von einem Speicherort an einen anderen

93

Ich möchte einen Klon der Struktur unseres Multi-Terabyte-Dateiservers erstellen. Ich weiß, dass cp --parents eine Datei und ihre übergeordnete Struktur verschieben können, aber gibt es eine Möglichkeit, die Verzeichnisstruktur intakt zu kopieren?

Ich möchte auf ein Linux-System kopieren und unser Dateiserver ist dort CIFS-gemountet.

r00fus
quelle
1
Mögliches Duplikat von Rsync, wie Verzeichnisse, aber keine Dateien einzuschließen?
Trevor Boyd Smith
Die rsync-Lösung aus dem obigen Kommentarbeitrag sieht ordentlicher aus.
Ja,

Antworten:

158

Sie könnten so etwas tun wie:

find . -type d > dirs.txt

um dann die Liste der Verzeichnisse zu erstellen

xargs mkdir -p < dirs.txt

um die Verzeichnisse am Ziel zu erstellen.

Greg Hewgill
quelle
8
Diese Lösung funktioniert nicht, wenn Ihre Verzeichnisnamen Leerzeichen enthalten.
Jealie
29
@Jealie Ändern Sie die Befehle in find . -type d -print0 >dirs.txtund xargs -0 mkdir -p <dirs.txt. Dies führt dazu, dass beide Befehle Nullen als Trennzeichen anstelle von Leerzeichen verwenden.
user1207177
3
xargskann die maximale Befehlslänge des Systems überschreiten, wenn Sie mit Bestellungen von Hunderten oder Tausenden beginnen. Verwenden Sie diese Option daher mit Vorsicht. (Finden Sie die Befehlslängenbeschränkung mit getconf ARG_MAX.) Bei vielen Verzeichnissen müssen Sie möglicherweise ein Skript schreiben, um stattdessen die Ausgabe zu durchlaufen.
Palswim
1
Und was ist mit Berechtigungen und Attributen, die beibehalten werden?
Ashish Karpe
3
@ TrevorBoydSmith: Danke für deinen Kommentar. In der ursprünglichen Frage wurde nichts darüber erwähnt, dass Berechtigungen, Eigentumsrechte oder Attribute beibehalten werden müssen. Dies würde, wie Sie bereits erwähnt haben, eine andere Lösung erfordern, aber das oben Genannte reicht aus, um die gestellte Frage zu beantworten.
Greg Hewgill
78
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
Amphetamachine
quelle
2
Beste Antwort von mir mit find. Andernfalls können Sie versuchen, die rsyncLösung von Chen Levy in dieser SO-Frage zu beantworten
Mat M
3
Was hat die Option - mkdir?
Bruce_Warrior
9
--ist ein Standard-Terminator für GNU-Dienstprogrammoptionen. Es bedeutet "hey mkdir, jedes Argument danach ist kein Flag, also behandeln Sie es als Dateiargument, auch wenn es mit einem '-' Zeichen beginnt."
Amphetamachine
4
Diese Antwort behält auch nicht die Verzeichnisberechtigungen und -attribute bei . Verwenden Sie rynsc, um die Berechtigungen und Attribute beizubehalten
Trevor Boyd Smith
34

Hier ist eine einfache Lösung mit rsync:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • eine Linie
  • Keine Probleme mit Leerzeichen
  • Berechtigungen beibehalten

Ich habe diese Lösung dort gefunden

Gildas
quelle
9
gleich, aber besser lesbarrsync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain
1
Das Problem bei dieser Lösung ist: Meine Ordner enthalten Tausende von Dateien und rsync benötigt Ewigkeiten, um ein Dutzend Ordner zu synchronisieren.
Christopher K.
6

Ich weiß nicht, ob Sie nach einer Lösung für Linux suchen. Wenn ja, können Sie Folgendes versuchen:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
Zerodin
quelle
cpio scheint bei mir nicht zu funktionieren, zumindest mit den von Ihnen angegebenen Parametern.
r00fus
@ r00fus - bitte lesen Sie das Handbuch für cpio oder beziehen Sie sich
zerodin
6

Dadurch werden die Verzeichnisse und Dateiattribute kopiert, nicht jedoch die Dateidaten:

cp -R --attributes-only SOURCE DEST

Dann können Sie die Dateiattribute löschen, wenn Sie nicht daran interessiert sind:

find DEST -type f -exec rm {} \;
Toliveira
quelle
1
Wäre exzellent, aber Sie haben vergessen, das Speichern von Eigentum, Zeitstempel und Berechtigungen zu erwähnen. Daher hat es in Win7 / cygwin ein Chaos verursacht - NULL_SID-Benutzer, falsche Berechtigungsreihenfolge, kann keine Berechtigungen bearbeiten usw. und kann nicht auf die erzeugte Dateistruktur zugreifen.
WebComer
1
Ich sollte denken, dass die Schuld direkt bei dem liegt, der versucht, Windows für echte Arbeit zu verwenden.
Tripleee
cp -R - nur Attribute --preserve = alle - Eltern -v QUELLENDEST
Gábor
2

Die folgende Lösung hat in verschiedenen Umgebungen für mich gut funktioniert:

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

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

Das funktioniert:

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

Ersetzen Sie einfach SOURCE_DIR und DEST_DIR.

mijhael3000
quelle
2

Dies löst sogar das Problem mit Leerzeichen:

Im Original- / Quellverzeichnis:

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

Erstellen Sie es dann im neu erstellten Verzeichnis neu:

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

Ersatz target_dirund source_dirmit den entsprechenden Werten:

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

Getestet unter OSX + Ubuntu.

luissquall
quelle
0

Ein Python-Skript von Sergiy Kolodyazhnyy, das auf Nur Ordner kopieren, keine Dateien? ::

#!/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)) 

oder aus der Shell:

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

Zu Ihrer Information:

Franck Dernoncourt
quelle
0

Ein anderer Ansatz ist die Verwendung des sehr treepraktischen und das Navigieren in Verzeichnisbäumen basierend auf seinen starken Optionen. Es gibt Optionen nur für Verzeichnisse, leere Verzeichnisse ausschließen, Namen mit Muster ausschließen, nur Namen mit Muster einschließen usw. Auscheckenman tree

Vorteil : Sie können die Liste bearbeiten oder überprüfen oder wenn Sie häufig Skripte erstellen und häufig einen Stapel leerer Verzeichnisse erstellen

Vorgehensweise : Erstellen Sie eine Liste von Verzeichnissen mit treeund verwenden Sie diese Liste als Argumenteingabe fürmkdir

tree -dfi --noreport > some_dir_file.txt

-dfi listet nur Verzeichnisse auf, druckt den vollständigen Pfad für jeden Namen, lässt den Baum die Einrückungszeilen nicht drucken,

--noreport Lässt das Drucken des Datei- und Verzeichnisberichts am Ende der Baumliste aus, damit die Ausgabedatei keine Flusen enthält

Gehen Sie dann zu dem Ziel, an dem Sie die leeren Verzeichnisse haben möchten, und führen Sie sie aus

xargs mkdir < some_dir_file.txt
Bruder-Bilo
quelle
0
find source/ -type f  | rsync -a --exclude-from - source/ target/

Kopieren Sie dir nur mit der zugehörigen Erlaubnis und dem zugehörigen Eigentum

Tiger Peng
quelle
0

1-Zeilen-Lösung:

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

Wenn Sie von einem Windows-Computer aus Zugriff erhalten, können Sie xcopy mit / T und / E verwenden, um nur die Ordnerstruktur zu kopieren (das / E enthält leere Ordner).

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

[BEARBEITEN!]

Dieser verwendet rsync, um die Verzeichnisstruktur neu zu erstellen, jedoch ohne die Dateien. http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

Könnte eigentlich besser sein :)

Dotalchemie
quelle
1
Leider führt unser CIFS-Serving-Dateiserver kein Windows aus, sodass dies bei Win-Befehlen nicht möglich ist.
r00fus
Vielen Dank, die rsync-Methode hat bei mir einwandfrei funktioniert. Es ist auch mit Leerzeichen in Verzeichnisnamen kompatibel.
Glutanimate
-1

Hier ist eine Lösung in PHP, die:

  • kopiert die Verzeichnisse (nicht rekursiv, nur eine Ebene)
  • behält Berechtigungen bei
  • Im Gegensatz zur rsync-Lösung ist es auch bei Verzeichnissen mit Tausenden von Dateien schnell, da es nicht einmal in die Ordner gelangt
  • hat keine Probleme mit Leerzeichen
  • sollte leicht zu lesen und einzustellen sein

Erstellen Sie eine Datei wie syncDirs.phpmit diesem Inhalt:

<?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());
}

Führen Sie es als Benutzer mit genügend Rechten aus:

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

Christopher K.
quelle
Sie müssen PHP nicht mögen und Sie müssen es nicht verwenden. Das OP hat jedoch nicht angegeben, ob er eine Lösung in einer bestimmten Sprache wünscht, und PHP wird trotzdem auf vielen Linux-Systemen installiert, da 80% des Webs PHP verwenden ( w3techs.com/technologies/details/pl-). PHP / alle / alle ).
Christopher K.