Nur Ordner kopieren, keine Dateien?

16

Gibt es eine Möglichkeit, ein gesamtes Verzeichnis zu kopieren, aber nur die Ordner? Ich habe irgendwo in meinem Verzeichnis eine beschädigte Datei, die dazu führt, dass meine Festplatten ausfallen.

Anstatt die beschädigte Datei auf eine andere Festplatte zu kopieren, wollte ich nur die Ordner kopieren, da ich Skripts habe, die nach Hunderten von Ordnern suchen, und nicht alle manuell erstellen müssen.

Ich habe das CP-Handbuch durchsucht, konnte aber nichts sehen (ich habe es möglicherweise verpasst)

Angenommen, ich habe diese Struktur auf meiner ausgefallenen Festplatte:

dir1
    files
    dir2
        files
        files
        dir4
dir3
files

Alles, was ich will, ist die Verzeichnisstruktur, überhaupt keine Dateien.

Also würde ich auf der neuen Festplatte landen:

dir1
    dir2
        dir4
dir3

Ich hoffe, jemand kennt ein paar Tricks!

Shannon
quelle
Wollen Sie nur die Verzeichnisstruktur kopieren oder wollen Sie nur die Dateien im aktuellen Arbeitsverzeichnis ausschließen (und alle anderen Dateien in tieferen Unterverzeichnissen sind Spieldateien)?
Oli
Ich habe ein Beispiel hinzugefügt. Entschuldigung für die Verwirrung
Shannon
1
Zu Ihrer Information, umrsync die Verzeichnisstruktur zu kopieren UND die Berechtigungen und Attribute beizubehalten ] ( stackoverflow.com/a/9242883/52074 ). Bei Verwendung von plain mkdir -p bleiben Berechtigungen und Attribute nicht erhalten .
Trevor Boyd Smith

Antworten:

15

Wenn Sie ein Verzeichnisskelett spiegeln und keine Dateien kopieren möchten:

find -type d -links 2 -exec mkdir -p "/path/to/backup/{}" \;

Was ist denn hier los:

  • Suchen wählt nur Verzeichnisse aus
  • Wir verwenden -links 2, um die tiefstmöglichen Verzeichnisse zu finden .
  • mkdir -p macht alle fehlenden Verzeichnisse auf dem Weg.

Ich habe es eher so gemacht, als find -type d -exec mkdir -p "/path/to/backup/{}" \;weil es bei einer ganzen Menge von mkdirAnrufen nicht funktioniert . Das können wir mit einem kleinen Test schnell beweisen. Hier ist der Testbaum, gefolgt von dem, was ich ausgeführt habe, um die beiden Befehle zu vergleichen:

$ tree
.
├── dir1
│   ├── dir2
│   │   └── dir3
│   ├── dir7
│   └── dir8
└── dir9
    └── dir0

$ pr -m -t <(find -type d) <(find -type d -links 2)
.                               ./dir1/dir8
./dir1                          ./dir1/dir2/dir3
./dir1/dir8                     ./dir1/dir7
./dir1/dir2                     ./dir9/dir0
./dir1/dir2/dir3
./dir1/dir7
./dir9                  
./dir9/dir0 

Und das wird nur in einer echten Lösung mit Tausenden von Verzeichnissen besser.

Oli
quelle
Ich bin ein Noob, aber wie suchen Sie das alte Verzeichnis, um es in das Backup zu kopieren? Ich kann hier nur einen Pfad sehen
Shannon
Wenn Sie keinen Pfad angeben, findwird das aktuelle Arbeitsverzeichnis als Ausgangspunkt verwendet. Wenn Sie einen anderen Pfad verwenden möchten, verwenden Sie die folgende Syntax:find /path/to/search/ -type.....
Oli
Also habe ich mein Verzeichnis auf einen bestimmten Ordner eingestellt, der das Gerüst enthält, das ich kopieren, ausführen find -type d -exec mkdir -p "/media/jinglez/TVSeries/TV Series"/{}" \;und alles sollte in Ordnung sein? Es scheint eine Weile
Shannon
Ich starte dies vom normalen Terminal aus, oder?
Shannon
1
Sie sind beide spezifisch für die exec-Klausel von find. {} bedeutet den aktuellen "gefundenen" Dateinamen und \; ist nur die Flucht, um die Klausel zu beenden. Wie es aussieht, gibt es eine zusätzliche "in Ihrem Code, bis nicht gut, ich bin sicher ... Sollte lauten:find -type d -links 2 -exec mkdir -p "/media/jinglez/TVSeries/TV Series/{}" \;
Oli
2

Mit Python One-Liner ganz einfach:

bash-4.3$ tree
.
├── ABC
├── set_pathname_icon.py
├── subdir1
│   ├── file1.abc
│   └── file2.abc
├── subdir2
│   ├── file1.abc
│   └── file2.abc
└── subdir3
    └── subdir4
        └── file1.txt

4 directories, 7 files
bash-4.3$ 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
bash-4.3$ tree ~/new_destination
/home/xieerqi/new_destination
├── subdir1
├── subdir2
└── subdir3
    └── subdir4

Als Skript könnte dies folgendermaßen umgeschrieben werden:

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