Skopiuj strukturę folderów (bez plików) z jednej lokalizacji do drugiej

100

Chcę stworzyć klon struktury naszego wieloterabajtowego serwera plików. Wiem, że cp --parents może przenieść plik i jego strukturę nadrzędną, ale czy istnieje sposób, aby skopiować strukturę katalogów w stanie nienaruszonym?

Chcę skopiować do systemu Linux, a nasz serwer plików jest tam zamontowany w CIFS.

r00fus
źródło
1
Możliwy duplikat Rsync, jak dołączyć katalogi, ale nie pliki?
Trevor Boyd Smith
Rozwiązanie rsync z powyższego komentarza wygląda ładniej.
YE

Odpowiedzi:

164

Możesz zrobić coś takiego:

find . -type d > dirs.txt

aby utworzyć listę katalogów, a następnie

xargs mkdir -p < dirs.txt

aby utworzyć katalogi w miejscu docelowym.

Greg Hewgill
źródło
8
To rozwiązanie nie zadziała, jeśli masz spacje w nazwach katalogów.
Jealie
33
@Jealie Zmień polecenia na find . -type d -print0 >dirs.txti xargs -0 mkdir -p <dirs.txt. Spowoduje to, że oba polecenia będą używać wartości null jako separatorów zamiast białych znaków.
user1207177
3
xargsmoże przekroczyć maksymalną długość polecenia systemu, gdy zaczynasz zajmować się zamówieniami liczącymi setki lub tysiące, więc używaj tego ostrożnie. (Znajdź limit długości polecenia za pomocą getconf ARG_MAX.) W przypadku wielu katalogów może być konieczne napisanie skryptu, który będzie przechodził przez wyjście.
palswim
1
A co z uprawnieniami i atrybutami, które zostaną zachowane?
Ashish Karpe,
3
@TrevorBoydSmith: Dziękuję za komentarz. Pierwotne pytanie nie wspominało nic o potrzebie zachowania uprawnień, własności lub atrybutów. Jak wspomniałeś, wymagałoby to innego rozwiązania, ale powyższe wystarczy, aby odpowiedzieć na postawione pytanie.
Greg Hewgill
82
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
amfetamachina
źródło
3
Najlepsza odpowiedź ode mnie z znajdź. W przeciwnym razie możesz wypróbować rsyncrozwiązanie z odpowiedzi Chen Levy w tym pytaniu SO
Mat M
3
Jaka jest opcja - mkdir?
Bruce_Warrior
10
--jest standardowym terminatorem opcji narzędziowych GNU. Oznacza "hej mkdir, każdy argument po tym, to nie jest flaga, więc traktuj go jako argument plikowy, nawet jeśli zaczyna się od znaku '-'."
amfetamachine
4
ta odpowiedź również nie zachowuje uprawnień i atrybutów katalogu . Użyj rynsc, aby zachować uprawnienia i atrybuty
Trevor Boyd Smith
39

Oto proste rozwiązanie wykorzystujące rsync:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • jedna linia
  • żadnych problemów ze spacjami
  • zachowaj uprawnienia

Tam znalazłem to rozwiązanie

Gildas
źródło
11
to samo, ale bardziej czytelnersync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain
1
Problem z tym rozwiązaniem jest następujący: moje foldery zawierają tysiące plików, a rsync trwa wieki, aby zsynchronizować kilkanaście folderów.
Christopher K.
7

Nie wiem, czy szukasz rozwiązania w systemie Linux. Jeśli tak, możesz spróbować tego:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
zerodin
źródło
Wydaje się, że cpio nie działa dla mnie, przynajmniej z określonymi przez Ciebie parametrami.
r00fus
@ r00fus - przeczytaj instrukcję obsługi cpio lub odwiedź gnu.org/software/cpio
zerodin
6

Spowoduje to skopiowanie katalogów i atrybutów plików, ale nie danych plików:

cp -R --attributes-only SOURCE DEST

Następnie możesz usunąć atrybuty plików, jeśli nie jesteś nimi zainteresowany:

find DEST -type f -exec rm {} \;
toliveira
źródło
1
Byłby doskonały, ale zapomniałeś wspomnieć o zapisaniu własności, sygnatury czasowej i uprawnień. Więc spowodował bałagan w Win7 / cygwin - użytkownik NULL_SID, zła kolejność uprawnień, nie może edytować uprawnień itp. I nie może uzyskać dostępu do utworzonej struktury plików.
WebComer
1
Myślę, że wina leży po prostu na tym, kto próbuje używać systemu Windows do prawdziwej pracy.
tripleee
cp -R --attributes-only --preserve = all --parents -v ŹRÓDŁO DEST
Gábor
2

Następujące rozwiązanie sprawdziło się u mnie w różnych środowiskach:

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

find "$sourceDir" -type d | sed -e "s?$sourceDir?$targetDir?" | xargs mkdir -p
yaccob
źródło
2

To działa:

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

Po prostu zastąp SOURCE_DIR i DEST_DIR.

mijhael3000
źródło
2

To rozwiązuje nawet problem z białymi znakami:

W oryginale / źródłowym reż .:

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

następnie odtwórz go w nowo utworzonym katalogu:

mkdir -p <../<SOURCEDIR>/dirs2.txt
Thim
źródło
1

Zastąp target_diri source_dirodpowiednimi wartościami:

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

Przetestowano na OSX + Ubuntu.

luissquall
źródło
0

Skrypt w języku Python napisany przez Sergiy Kolodyazhnyy opublikowany na: Kopiować tylko foldery, a nie pliki? :

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

lub z muszli:

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
źródło
0

Innym podejściem jest użycie treebardzo poręcznego i nawigowanie po drzewach katalogów w oparciu o jego mocne opcje. Dostępne są opcje tylko dla katalogu, wyklucz puste katalogi, wyklucz nazwy ze wzorcem, uwzględnij tylko nazwy ze wzorcem itp. Sprawdźman tree

Zaleta : możesz edytować lub przeglądać listę lub jeśli wykonujesz dużo skryptów i często tworzysz zestaw pustych katalogów

Podejście : utwórz listę katalogów używając tree, użyj tej listy jako argumentów wejściowychmkdir

tree -dfi --noreport > some_dir_file.txt

-dfi wyświetla tylko katalogi, wyświetla pełną ścieżkę dla każdej nazwy, sprawia, że ​​drzewo nie wypisuje linii wcięć,

--noreport Pomija drukowanie raportu o pliku i katalogu na końcu listy drzewa, aby plik wyjściowy nie zawierał żadnych kłaczków

Następnie przejdź do miejsca docelowego, w którym chcesz puste katalogi i wykonaj

xargs mkdir < some_dir_file.txt
brat-bilo
źródło
0
find source/ -type f  | rsync -a --exclude-from - source/ target/

Kopiuj katalog tylko z powiązanymi uprawnieniami i własnością

Tiger Peng
źródło
0

Rozwiązanie 1-liniowe:

find . -type d -exec mkdir -p /path/to/copy/directory/tree/{} \;
Igor
źródło
-1

Jeśli możesz uzyskać dostęp z komputera z systemem Windows, możesz użyć xcopy z / T i / E, aby skopiować tylko strukturę folderów (/ E zawiera puste foldery)

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

[EDYTOWAĆ!]

Ten używa rsync do odtworzenia struktury katalogów, ale bez plików. http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

Właściwie może być lepiej :)

dotalchemy
źródło
1
Niestety, nasz serwer plików obsługujący CIFS nie działa w systemie Windows, więc nie można tego zrobić w przypadku poleceń win.
r00fus
Dziękuję, metoda rsync zadziałała dla mnie idealnie. Jest również kompatybilny ze spacjami w nazwach katalogów.
Glutanimate
-1

Oto rozwiązanie w PHP, które:

  • kopiuje katalogi (nie rekurencyjnie, tylko jeden poziom)
  • zachowuje uprawnienia
  • w przeciwieństwie do rozwiązania rsync, działa szybko nawet w przypadku katalogów zawierających tysiące plików, ponieważ nie przechodzi nawet do folderów
  • nie ma problemów ze spacjami
  • powinien być łatwy do odczytania i dostosowania

Utwórz plik podobny syncDirs.phpdo tej zawartości:

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

Uruchom go jako użytkownik, który ma wystarczające uprawnienia:

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

Christopher K.
źródło
Nie musisz lubić PHP i nie musisz go używać. Ale OP nie sprecyzował, czy chce rozwiązania w jakimkolwiek konkretnym języku i, czy mu się to podoba, czy nie, PHP i tak jest instalowane w wielu systemach Linux, ponieważ 80% sieci używa PHP ( w3techs.com/technologies/details/pl- php / all / all ).
Christopher K.,