Salin struktur folder (tanpa file) dari satu lokasi ke lokasi lain

96

Saya ingin membuat tiruan dari struktur server file multi-terabyte kami. Saya tahu bahwa cp --parents dapat memindahkan file dan itu struktur induk, tetapi adakah cara untuk menyalin struktur direktori secara utuh?

Saya ingin menyalin ke sistem linux dan server file kami dipasang CIFS di sana.

r00fus
sumber
1
Kemungkinan duplikat Rsync bagaimana menyertakan direktori tetapi bukan file?
Trevor Boyd Smith
solusi rsync dari posting komentar di atas terlihat lebih rapi.
YE

Jawaban:

159

Anda bisa melakukan sesuatu seperti:

find . -type d > dirs.txt

untuk membuat daftar direktori, lalu

xargs mkdir -p < dirs.txt

untuk membuat direktori di tujuan.

Greg Hewgill
sumber
8
Solusi ini tidak akan berfungsi jika Anda memiliki spasi di nama direktori Anda.
Jealie
32
@Jealie Ubah perintah menjadi find . -type d -print0 >dirs.txtdan xargs -0 mkdir -p <dirs.txt. Ini akan menyebabkan kedua perintah menggunakan null sebagai pemisah, bukan spasi.
pengguna1207177
3
xargsdapat melebihi panjang perintah maksimum sistem saat Anda mulai menangani ratusan atau ribuan pesanan, jadi gunakan ini dengan hati-hati. (Temukan batas panjang perintah dengan getconf ARG_MAX.) Dengan banyak direktori, Anda mungkin harus menulis skrip untuk mengulang keluaran.
palswim
1
Dan bagaimana dengan hak akses & atribut apakah akan dipertahankan ??
Ashish Karpe
3
@TrevorBoydSmith: Terima kasih atas komentar Anda. Pertanyaan awal tidak menyebutkan apa pun tentang perlunya mempertahankan izin, kepemilikan, atau atribut. Melakukannya akan membutuhkan solusi yang berbeda, seperti yang Anda sebutkan, tetapi di atas sudah cukup untuk menjawab pertanyaan seperti yang diajukan.
Greg Hewgill
80
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;
amfetamachine
sumber
3
Jawaban terbaik dari saya dengan find. Lain Anda dapat mencoba rsyncsolusi dari jawaban Chen Levy dalam pertanyaan SO ini
Mat M
3
Apa yang dimaksud dengan opsi - mkdir?
Bruce_Warrior
10
--adalah terminator opsi utilitas GNU standar. Artinya "hai mkdir, argumen apa pun setelah ini, ini bukan sebuah bendera, jadi perlakukan itu sebagai argumen file, bahkan jika itu dimulai dengan karakter '-'."
amphetamachine
4
jawaban ini juga tidak mempertahankan izin dan atribut direktori . Gunakan rynsc untuk mempertahankan izin dan atribut
Trevor Boyd Smith
36

Berikut adalah solusi sederhana menggunakan rsync:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • satu baris
  • tidak ada masalah dengan spasi
  • mempertahankan izin

Saya menemukan solusi ini di sana

Gildas
sumber
11
sama tetapi lebih mudah dibacarsync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain
1
Masalah dengan solusi ini adalah: folder saya berisi ribuan file dan rsync membutuhkan waktu lama hanya untuk menyinkronkan lusinan folder.
Christopher K.
6

Saya tidak tahu jika Anda mencari solusi di Linux. Jika demikian, Anda dapat mencoba ini:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir
zerodin
sumber
cpio tampaknya tidak berfungsi untuk saya, setidaknya dengan parameter yang Anda tentukan.
r00fus
@ r00fus - harap baca manual untuk cpio atau lihat gnu.org/software/cpio
zerodin
6

Ini menyalin atribut direktori dan file, tetapi bukan data file:

cp -R --attributes-only SOURCE DEST

Kemudian Anda dapat menghapus atribut file jika Anda tidak tertarik padanya:

find DEST -type f -exec rm {} \;
toliveira
sumber
1
Akan sangat bagus, tetapi Anda lupa menyebutkan menyimpan kepemilikan, stempel waktu, dan izin. Jadi itu menghasilkan kekacauan di Win7 / cygwin - pengguna NULL_SID, urutan izin yang salah, tidak dapat mengedit izin, dll dan tidak dapat mengakses struktur file yang dihasilkan.
WebComer
1
Saya harus berpikir bahwa kesalahan terletak tepat pada siapa pun yang mencoba menggunakan Windows untuk pekerjaan nyata.
tripleee
cp -R --attributes-only --preserve = all --parents -v SOURCE DEST
Gábor
2

Solusi berikut bekerja dengan baik untuk saya di berbagai lingkungan:

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

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

Ini bekerja:

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

Cukup ganti SOURCE_DIR dan DEST_DIR.

mijhael3000
sumber
2

Ini bahkan memecahkan masalah dengan spasi:

Di direktori asli / sumber:

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

lalu buat ulang di direktori yang baru dibuat:

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

Gantikan target_dirdan source_dirdengan nilai yang sesuai:

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

Diuji di OSX + Ubuntu.

luissquall
sumber
0

Skrip python dari Sergiy Kolodyazhnyy diposting di Salin hanya folder, bukan file? :

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

atau dari cangkang:

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
sumber
0

Pendekatan lain adalah menggunakan treeyang cukup berguna dan menavigasi pohon direktori berdasarkan opsi yang kuat. Ada opsi untuk direktori saja, kecualikan direktori kosong, kecualikan nama dengan pola, sertakan hanya nama dengan pola, dll. Periksaman tree

Keuntungan : Anda dapat mengedit atau meninjau daftar, atau jika Anda melakukan banyak skrip dan sering membuat sekumpulan direktori kosong

Pendekatan : buat daftar direktori menggunakan tree, gunakan daftar itu sebagai masukan argumenmkdir

tree -dfi --noreport > some_dir_file.txt

-dfi mencantumkan hanya direktori, mencetak jalur lengkap untuk setiap nama, membuat pohon tidak mencetak baris indentasi,

--noreport Menghilangkan pencetakan file dan laporan direktori di akhir daftar pohon, hanya untuk membuat file keluaran tidak mengandung fluff apapun

Lalu pergi ke tujuan di mana Anda ingin direktori kosong dan jalankan

xargs mkdir < some_dir_file.txt
saudara-bilo
sumber
0
find source/ -type f  | rsync -a --exclude-from - source/ target/

Salin direktori hanya dengan izin dan kepemilikan terkait

Tiger peng
sumber
0

Solusi 1 baris:

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

Jika Anda bisa mendapatkan akses dari mesin Windows, Anda dapat menggunakan xcopy dengan / T dan / E untuk menyalin hanya struktur folder (/ E menyertakan folder kosong)

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

[EDIT!]

Yang ini menggunakan rsync untuk membuat ulang struktur direktori tetapi tanpa file. http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

Mungkin lebih baik :)

dotalchemy
sumber
1
Sayangnya, server file yang melayani CIFS kami tidak menjalankan windows, jadi tidak ada yang bisa dilakukan pada perintah win.
r00fus
Terima kasih, metode rsync bekerja dengan baik untuk saya. Ini kompatibel dengan spasi dalam nama direktori juga.
Glutanimate
-1

Berikut adalah solusi di php yang:

  • menyalin direktori (tidak secara rekursif, hanya satu tingkat)
  • mempertahankan izin
  • tidak seperti solusi rsync, cepat bahkan dengan direktori yang berisi ribuan file karena tidak masuk ke folder
  • tidak memiliki masalah dengan spasi
  • harus mudah dibaca dan disesuaikan

Buat file seperti syncDirs.phpdengan konten ini:

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

Jalankan sebagai pengguna yang memiliki hak yang cukup:

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

Christopher K.
sumber
Anda tidak harus menyukai PHP dan Anda tidak harus menggunakannya. Tetapi OP tidak menentukan apakah dia menginginkan solusi dalam bahasa tertentu dan, suka atau tidak, PHP diinstal pada banyak sistem Linux karena 80% web menggunakan PHP ( w3techs.com/technologies/details/pl- php / all / all ).
Christopher K.