Antworten:
Versuche dies,
cd /source/dir/path
find . -type d -exec mkdir -p -- /destination/directory/{} \;
. -type d
Verzeichnisse im aktuellen Pfad rekursiv auflisten.mkdir -p -- /destination/directory/{}
Verzeichnis am Ziel erstellen. Dies beruht auf einem find
, das das Erweitern {}
in der Mitte eines Argumentworts unterstützt.
/source/dir/path
, dann könnte dies mit einer „Argumentliste zu lang“ fail Fehler , wenn die Shell versucht, rufen Sie find
mit der Erweiterung der *
. Besser nur .
dort zu verwenden. Die meisten find
Implementierungen können {}
auch verwendet werden, wenn sie mit einer anderen Zeichenfolge verknüpft sind, dies ist jedoch nicht universell.
.
Statt *
in diesem Fall verwenden. (Die Verwendung von xarg für Leistung und Sicherheit würde wahrscheinlich ein externes Skript für die
Verwenden von rsync
:
rsync -a --include='*/' --exclude='*' /some/path/dir/ dir
Dies würde die Verzeichnisstruktur /some/path/dir
wie dir
im aktuellen Verzeichnis neu erstellen , ohne Dateien zu kopieren.
Jedes Verzeichnis, das im Quellpfad gefunden wird, wird aufgrund des Einschlussmusters am Ziel erstellt, alles andere wird jedoch ausgeschlossen. Als Nebeneffekt von using -a
( --archive
) erhalten Sie für alle Unterverzeichnisse im Ziel dieselben Zeitstempel wie in der Quelle. Dies funktioniert auch zum Erstellen lokaler Verzeichnisstrukturen aus Remote-Verzeichnissen (und umgekehrt).
rsync
!
Sie können find
die Quellstruktur durchlaufen und mkdir
jedes Verzeichnis aufrufen, auf das sie trifft.
In diesem Beispiel wird mit verwendet find
, um Ihre Verzeichnisstruktur von foo
nach zu kopieren/tmp/another/
( cd foo && find -type d -exec sh -c 'for d do mkdir -p "/tmp/another/$d"; done' sh {} + )
Die exec
Schleife baut die darunter liegenden Verzeichnisse auf foo
, die dann an die übergeben werden mkdir
. Wenn Sie keine Version davon haben find
, +
können Sie diese \;
auf Kosten der Effizienz verwenden. Ersetzen Sie mkdir
durch, um echo mkdir
zu sehen, was passieren würde, ohne es tatsächlich zu tun.
... -exec sh -c 'for dirpath do mkdir -p "/some/path/$dirpath"; done' sh {} +
find: In ‘-exec ... {} +’ the ‘{}’ must appear by itself, but you specified ‘/tmp/another/{}’
(es funktioniert jedoch mit -exec ... \;
)
/path/to/{}
aber ich kann jetzt keine Version finden, in der es funktioniert, also habe ich die Lösung angepasst. Vielen Dank
Mit der Bash-Shell können Sie nach der Erweiterung jedes Verzeichnisses mit der globstar
Option fragen :
shopt -s globstar
und kopieren Sie dann die Verzeichnisse mit einer Schleife:
for dir in **/
do
mkdir -p /path/to/dest/"$dir"
done
... oder wenn Sie dachten, sie würden alle in einen Anruf passen mkdir
:
set -- **/
mkdir -- "${@/#//path/to/dest/}"
Das ist die Bash-Array-Syntax, die besagt: "Nehmen Sie jedes Element des $@
Arrays und ersetzen Sie den Anfang jedes Elements durch /path/to/dest/
.
Mir ist keine Möglichkeit bekannt, ls
direkt als Klammererweiterungsliste auszugeben. Wenn Sie versuchen, die Ausgabe der **/
Erweiterung in eine Klammererweiterung zu massieren , müssen Sie Folgendes beachten:
{
oder einer ${
SequenzIch würde es nicht empfehlen.
Die Frage ist ein Cross-Site-Duplikat von /superuser/1389580/copy-directory-structure-only-at-year-end
Diese Art von Aufgabe ist ein klassischer Anwendungsfall für mtree
:
$ mkdir new-tree
$ mtree -cp old-tree | mtree -tdUp new-tree
.: modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
./bar missing (created)
./bar/bar2 missing (created)
./bar/bar2/bar3 missing (created)
./bar/bar2/bar3/bar4 missing (created)
./foo missing (created)
./foo/foo2 missing (created)
./foo/foo2/foo3 missing (created)
Das obige erstellt alle Verzeichnisse unter new-tree
, die unter vorhanden waren old-tree
. mtree
setzt jedoch keine Zeitstempel für neu erstellte Verzeichnisse, sodass der resultierende Baum folgendermaßen aussieht:
$ find old-tree new-tree -ls
20147 1 drwx--x--- 4 jim jim 5 Sep 24 14:27 old-tree
20048 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/foo
20363 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/file
20073 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/foo/foo2
20074 1 drwx--x--- 2 jim jim 3 Sep 24 14:27 old-tree/foo/foo2/foo3
20365 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/foo2/foo3/file
20364 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/foo2/file
20051 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar
20077 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar/bar2
20368 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/file
20078 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar/bar2/bar3
20369 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/bar3/file
20079 1 drwx--x--- 2 jim jim 3 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4
20370 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4/file
20366 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/file
20362 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/file
134489 1 drwx--x--- 4 jim jim 4 Sep 24 16:34 new-tree
134490 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/bar
134491 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/bar/bar2
134492 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/bar/bar2/bar3
134493 1 drwx--x--- 2 jim jim 2 Sep 24 16:34 new-tree/bar/bar2/bar3/bar4
134494 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/foo
134495 1 drwx--x--- 3 jim jim 3 Sep 24 16:34 new-tree/foo/foo2
134496 1 drwx--x--- 2 jim jim 2 Sep 24 16:34 new-tree/foo/foo2/foo3
Wenn Sie möchten, dass die new-tree
Zeitstempel mit denen in übereinstimmen old-tree
, führen Sie sie einfach mtree
erneut aus. Da die Verzeichnisse bereits vorhanden sind, mtree
werden die Zeitstempel an die Quellenspezifikation angepasst:
$ mtree -cp old-tree | mtree -tdUp new-tree
.: modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar: modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2/bar3:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
bar/bar2/bar3/bar4:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo: modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo/foo2:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
foo/foo2/foo3:
modification time (Tue Sep 24 14:27:07 2019, Tue Sep 24 16:34:57 2019, modified)
$ find old-tree new-tree -ls
20147 1 drwx--x--- 4 jim jim 5 Sep 24 14:27 old-tree
20048 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/foo
20363 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/file
20073 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/foo/foo2
20074 1 drwx--x--- 2 jim jim 3 Sep 24 14:27 old-tree/foo/foo2/foo3
20365 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/foo2/foo3/file
20364 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/foo/foo2/file
20051 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar
20077 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar/bar2
20368 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/file
20078 1 drwx--x--- 3 jim jim 4 Sep 24 14:27 old-tree/bar/bar2/bar3
20369 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/bar3/file
20079 1 drwx--x--- 2 jim jim 3 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4
20370 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/bar2/bar3/bar4/file
20366 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/bar/file
20362 1 -rw------- 1 jim jim 0 Sep 24 14:27 old-tree/file
134489 1 drwx--x--- 4 jim jim 4 Sep 24 14:27 new-tree
134490 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/bar
134491 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/bar/bar2
134492 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/bar/bar2/bar3
134493 1 drwx--x--- 2 jim jim 2 Sep 24 14:27 new-tree/bar/bar2/bar3/bar4
134494 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/foo
134495 1 drwx--x--- 3 jim jim 3 Sep 24 14:27 new-tree/foo/foo2
134496 1 drwx--x--- 2 jim jim 2 Sep 24 14:27 new-tree/foo/foo2/foo3
find
die Interpolation{}
in einen anderen String unterstützt.