Klasör yapısını (dosyasız) bir konumdan diğerine kopyalayın


100

Çok terabaytlı dosya sunucumuzun yapısının bir klonunu oluşturmak istiyorum. Cp --parents'ın bir dosyayı ve onun üst yapısını taşıyabileceğini biliyorum, ancak dizin yapısını bozulmadan kopyalamanın bir yolu var mı?

Bir linux sistemine kopyalamak istiyorum ve dosya sunucumuz CIFS oraya bağlı.



Yukarıdaki yorum gönderisindeki rsync çözümü daha düzgün görünüyor.
YE

Yanıtlar:


164

Şunun gibi bir şey yapabilirsiniz:

find . -type d > dirs.txt

dizin listesini oluşturmak için, ardından

xargs mkdir -p < dirs.txt

Hedefte dizinleri oluşturmak için.


8
Dizin adlarınızda boşluk varsa bu çözümler çalışmayacaktır.
Jealie

33
@Jealie Komutları find . -type d -print0 >dirs.txtve olarak değiştirin xargs -0 mkdir -p <dirs.txt. Bu, her iki komutun da boşluk yerine boş değerleri ayırıcı olarak kullanmasına neden olur.
user1207177

3
xargsYüzlerce veya binlerce siparişle uğraşmaya başladığınızda sistemin maksimum komut uzunluğunu aşabilir, bu nedenle bunu dikkatli kullanın. ( getconf ARG_MAXİle komut uzunluğu sınırını bulun .) Çok sayıda dizinde, bunun yerine çıktıda döngü yapmak için bir komut dosyası yazmanız gerekebilir.
palswim

1
Peki ya izinler ve öznitelikler korunacak mı?
Ashish Karpe

3
@TrevorBoydSmith: Yorumunuz için teşekkürler. Asıl soru, izinleri, sahipliği veya öznitelikleri korumanın gerekliliğinden bahsetmiyordu. Bunu yapmak, belirttiğiniz gibi farklı bir çözüm gerektirir, ancak yukarıdakiler soruyu sorulduğu gibi cevaplamak için yeterlidir.
Greg Hewgill

82
cd /path/to/directories &&
find . -type d -exec mkdir -p -- /path/to/backup/{} \;

3
Bul ile benden en iyi cevap. Aksi takdirde, bu SO sorusundakirsync Chen Levy cevabının çözümünü deneyebilirsiniz
Mat M

3
- mkdir seçeneği nedir?
Bruce_Warrior

10
--standart bir GNU yardımcı program seçeneği sonlandırıcısıdır. Bu, "hey mkdir, bundan sonraki herhangi bir argüman, bu bir bayrak değil, bu nedenle bir '-' karakteriyle başlasa bile onu bir dosya argümanı olarak ele alın." Anlamına gelir.
amphetamachine

4
bu yanıt , dizin izinlerini ve özniteliklerini de korumaz . İzinleri ve öznitelikleri korumak için rynsc kullanın
Trevor Boyd Smith

39

İşte rsync kullanan basit bir çözüm:

rsync -av -f"+ */" -f"- *" "$source" "$target"
  • Tek çizgi
  • boşluklarla ilgili sorun yok
  • izinleri koru

Bu çözümü orada buldum


11
aynı ama daha okunaklırsync -a --include '*/' --exclude '*' "$source" "$target"
Sylvain

1
Bu çözümle ilgili sorun şu: klasörlerim binlerce dosya içeriyor ve rsync yalnızca bir düzine klasörü senkronize etmek için zaman alıyor.
Christopher K.

7

Linux'ta bir çözüm arıyorsanız bilmiyorum. Eğer öyleyse, şunu deneyebilirsiniz:

$ mkdir destdir
$ cd sourcedir
$ find . -type d | cpio -pdvm destdir

cpio, en azından belirttiğiniz parametrelerle benim için çalışmıyor gibi görünüyor.
r00fus

@ r00fus - lütfen cpio kılavuzunu okuyun veya gnu.org/software/cpio'ya
zerodin

6

Bu, dizinleri ve dosya özniteliklerini kopyalar, ancak dosya verilerini kopyalamaz:

cp -R --attributes-only SOURCE DEST

Ardından, ilgilenmiyorsanız dosya özniteliklerini silebilirsiniz:

find DEST -type f -exec rm {} \;

1
Mükemmel olurdu ama sahiplik, zaman damgası ve izinleri kaydetmeyi unuttunuz. Bu yüzden Win7 / cygwin - NULL_SID kullanıcısı, yanlış izin sırası, izinleri düzenleyemeyen vb. Bir karmaşa üretti ve üretilen dosya yapısına erişemez.
WebComer

1
Suçun, Windows'u gerçek iş için kullanmaya çalışan herkesin üzerinde olduğunu düşünmeliyim.
üçlü

cp -R - yalnızca öznitelikler --preserve = all --parents -v KAYNAK HEDEF
Gábor

2

Aşağıdaki çözüm, çeşitli ortamlarda benim için iyi çalıştı:

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

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

2

Bu çalışıyor:

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

SOURCE_DIR ve DEST_DIR'i değiştirmeniz yeterlidir.


2

Bu, beyaz boşluklarla ilgili sorunu bile çözer:

Orijinal / kaynak dizininde:

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

sonra yeni oluşturulan dizinde yeniden oluşturun:

mkdir -p <../<SOURCEDIR>/dirs2.txt

1

Değiştirin target_dirve source_diruygun değerlerle:

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

OSX + Ubuntu'da test edilmiştir.


0

Sergiy Kolodyazhnyy'den bir python betiği dosyaları değil, yalnızca klasörleri kopyala? :

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

veya kabuktan:

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

Bilginize:


0

Diğer bir yaklaşım, treeoldukça kullanışlı olan ve güçlü seçeneklerine göre dizin ağaçlarında gezinen kullanmaktır . Yalnızca dizin için seçenekler vardır, boş dizinleri hariç tutma, kalıplı adları hariç tutma, yalnızca kalıplı adları dahil etme vb.man tree

Avantaj : Listeyi düzenleyebilir veya gözden geçirebilirsiniz veya çok sayıda komut dosyası yazıp sık sık boş dizinler topluyorsanız

Yaklaşım : kullanarak bir dizin listesi oluşturun tree, bu listeyi bir argüman girişi olarak kullanınmkdir

tree -dfi --noreport > some_dir_file.txt

-dfi sadece dizinleri listeler, her isim için tam yolu yazdırır, ağacın girinti çizgilerini yazdırmamasını sağlar,

--noreport Çıktı dosyasının herhangi bir tüy içermemesi için ağaç listesinin sonunda dosya ve dizin raporunun yazdırılmasını atlar

Ardından boş dizinlerin olmasını istediğiniz hedefe gidin ve

xargs mkdir < some_dir_file.txt

0
find source/ -type f  | rsync -a --exclude-from - source/ target/

Dizini yalnızca ilişkili izin ve sahiplikle kopyalayın


0

1 hat çözümü:

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

-1

Bir Windows makinesinden erişebiliyorsanız, yalnızca klasör yapısını kopyalamak için / T ve / E ile xcopy kullanabilirsiniz (/ E, boş klasörleri içerir)

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

[DÜZENLE!]

Bu, dosyalar olmadan dizin yapısını yeniden oluşturmak için rsync kullanır. http://psung.blogspot.com/2008/05/copying-directory-trees-with-rsync.html

Aslında daha iyi olabilir :)


1
Ne yazık ki, CIFS hizmet veren dosya sunucumuz pencereleri çalıştırmıyor, bu nedenle kazan komutları üzerinde kimse yapamaz.
r00fus

Teşekkürler, rsync yöntemi benim için mükemmel çalıştı. Dizin adlarındaki boşluklarla da uyumludur.
Glutanimate

-1

İşte php'de bir çözüm:

  • dizinleri kopyalar (yinelemeli değil, yalnızca bir düzey)
  • izinleri korur
  • rsync çözümünün aksine binlerce dosya içeren dizinlerde bile hızlıdır çünkü klasörlere bile girmez
  • boşluklarla sorunu yok
  • okunması ve ayarlanması kolay olmalı

syncDirs.phpBu içeriğe benzer bir dosya oluşturun :

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

Yeterli haklara sahip bir kullanıcı olarak çalıştırın:

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


PHP'yi sevmek zorunda değilsiniz ve kullanmak zorunda değilsiniz. Ancak OP, herhangi belirli bir dilde bir çözüm isteyip istemediğini belirtmedi ve beğenin ya da beğenmeyin , web'in% 80'i PHP ( w3techs.com/technologies/details/pl- php / tümü / tümü ).
Christopher K.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.