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.



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.


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/{} \;

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


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

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 {} \;

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

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.


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

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.


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:


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

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


0

1-Zeilen-Lösung:

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

-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 :)


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


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.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.