İki dizin nasıl birleştirilir?


112

Linux'ta bu yapı ile iki dizin görüntüleri ve görüntüler2 var:

/images/ad  
/images/fe  
/images/foo  

... ve diğer 4000 klasör

ve diğeri şöyle:

/images2/ad  
/images2/fe  
/images2/foo

... ve diğer 4000 klasör

Bu klasörlerin her biri görüntüler içerir ve dizinlerin görüntüler ve görüntüler altındaki2 adları tamamen aynıdır, ancak içerikleri farklıdır. Sonra / images2 / ad resimlerini resimlere / reklamlara, / images2 / foo resimlerini resimlere / foo resimlerine nasıl kopyalayabileceğimi bilmek istiyorum.


1
her iki klasörde aynı adlı son dosyalar?
Simply_Me

Hayır ... örneğin resimlerde / reklamlarda 1.jpg, 2.jpg ve 3.jpg. Ancak
images2

4
@AmirAliAkbari, bunun yinelenen olduğunu düşünmüyorum - diğer soru temel olarak 'mv birleşiyor mu?' (cevap: hayır). Bu soru 2 dizin hiyerarşisinin nasıl birleştirileceği ile ilgilidir.
maxschlepzig

Yanıtlar:


173

Bu rsync için bir iş . Dosyayı kopyalamak yerine taşımak istemediğiniz sürece, bunu bir kabuk döngüsüyle el ile yapmanın faydası yoktur.

rsync -a /path/to/source/ /path/to/destination

Senin durumunda:

rsync -a /images2/ /images/

(Sondaki eğik çizgiyi not alın images2, aksi takdirde kopyalar /images/images2.)

Aynı isimde görüntüleri her iki dizine de varsa, yukarıdaki komut üzerine yazacaktır /images/SOMEPATH/SOMEFILEile /images2/SOMEPATH/SOMEFILE. Yalnızca daha eski dosyaları değiştirmek istiyorsanız, seçeneği ekleyin -u. Sürümü daima içinde tutmak istiyorsanız /images, seçeneği ekleyin --ignore-existing.

Dosyaları taşımak isterseniz /images2, rsync ile seçeneği geçebilirsiniz --remove-source-files. Sonra rsync tüm dosyaları sırayla kopyalar ve bittiğinde her bir dosyayı kaldırır. Kaynak ve hedef dizinleri aynı dosya sistemindeyse, bu, hareket etmekten çok daha yavaştır.


14
..add -P ilerlemeyi görmek istiyorsanız ..
Meetai.com

1
Ben bile burada zor kabuk döngü kullanmaya hiçbir yararı var olduğunu eklemek istiyorum do onları-sadece kullandıkları durumda kopyalamak yerine taşımak istiyorum rsync, sonra rm -r /images.
Wildcard

1
Her dizin için sondaki eğik çizgileri eklemenin önemli olduğunu da belirtmek isterim . Örneğin, basitçe rsync -a images images2koştuysanız, sadece birleştirmek yerine images2'ye kopyalar.
Kyle Challis

1
@ s3cur3 Oh. 2'den (üstü) 1. Bu sezgisel değildir. Teşekkürler, cevabımı düzelttim.
Gilles

1
@ MaxCoplan No. Rsync etkileşimli bir araç değildir.
Gilles

43

Daha önce de belirtildiği gibi en iyi seçenek elbette rsync. Bununla birlikte, birlikte çalışmak da bu işi yapmak için harika bir yazılım olacaktır. Her ikisi de birkaç işletim sisteminde kullanılabilir.

Rsync

rsync, kaynaktan hedefe bir yönde senkronize eder. Bu nedenle aşağıdaki ifade

rsync -avh --progress Source Destination

Kaynaktan Hedefe kadar her şeyi senkronize eder . Birleştirilmiş klasör içinde bulunduğu Hedef .

-a "arşiv" anlamına gelir ve hemen hemen her şeyi koruyarak tekrarlayan her şeyi kaynağından hedefe kopyalar.

-v daha fazla çıktı verir ("ayrıntılı").

-h insan tarafından okunabilir.

- ne kadar iş yapıldığını gösteren ilerleme .

Yalnızca istiyorsanız güncelleme hedef klasörü yeni ile kaynak klasörden dosyaları:

rsync -avhu --progress source destination

ahenk

unison her iki yönde de senkronize edilir. Bu nedenle aşağıdaki ifade

unison Source Destination

her iki dizini de her iki yönde de senkronize eder ve son olarak kaynak hedef eşittir. Kaynaktan desteye ve tersinden iki defa rsync yapmak gibi.

Daha gelişmiş kullanımlar için man sayfalarına veya aşağıdaki web sitelerine bakın:

  1. https://www.cis.upenn.edu/~bcpierce/unison/
  2. https://rsync.samba.org/

2
Klasöre giden doğru yolun sonunda bir eğik çizgi olması gerektiğini belirtmeliyim rsync -avh --progress source/ destination/, aksi takdirde kaynak klasör hedef klasörde, en azından benim durumumda oluşturulacak.
electroid

Bu benim için harika (klasörlerdeki izleyen eğik çizgi ile). Teşekkür ederim!
Leopoldo Sanczyk

5
for dir in images2/*; do mv "$dir"/* "images/$(basename "$dir")"; done

images2Genişletilmiş bir glob kullanmanın tüm içeriğini ( ayrıştırma ile ilgili sorunları önlemek için ls) daha sonra mvbu öğelerin içeriğini eşleşen girişe dönüştürün images. Kullanımları basenamelider şerit images2globbed yolundan.


lütfen emrinizin ne yaptığına dair daha fazla ayrıntı ekleyin, böylece gelecekteki okuyucular için de yararlı olacaktır :)
Ramesh

1

@ inulinux12, forkomut satırından aşağıdaki bir satır döngüsünü kullanabilirsiniz :

$ for dir in images2/*; do mv "$dir"/* "${dir/2/}"; done

Bu dosyaların tümünü hareket edecek images2için imageskendi dizinleri. Not: Bu, hiçbir dosyanın aynı ada sahip olmadığını varsayar.

Örneğin:

İnfazdan önce:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2
images/adfoo:
jpg.7
images/fe:
jpg.5
images2:
ad  adfoo  fe
images2/ad:
jpg.3
images2/adfoo:
jpg.6
images2/fe:
jpg.4

İdamdan sonra:

$ ls -R images*
images:
ad  adfoo  fe
images/ad:
jpg.1  jpg.2  jpg.3
images/adfoo:
jpg.6  jpg.7
images/fe:
jpg.4  jpg.5

3
Çıktısını ayrıştırma ls. mywiki.wooledge.org/ParsingLs
Etan Reisner

@EtanReisner Öneriniz için teşekkür ederiz; soruda verilen bilgiyi vermemize rağmen oldukça dar senaryolar görünüyor.
Simply_Me,

2
@Simply_Me Genelde iyi olacağı doğru olsa da, güvenmediğiniz bir davaya çarptığınızda patlamasını istemezsiniz. Gerçekten kötü sorunlara neden olabilir . Oldukça sık (bu örnekte olduğu gibi) basit bir küre ile neredeyse trivally değiştirilebileceğinden bahsetmiyorum. Cevabımı bunun bir örneği olarak görün.
Etan Reisner,

@Simply_Me Senaryolar, görüntüler için oldukça yaygın olan boşluklu dosya adlarını içerir.
Gilles,

@Gilles ve @Etan Reisner, katılımınız için teşekkür ederim, takdir ediyorum! Dize değiştirme kullanmak için cevabım güncellendi ve test edildi ve basenamebu özel durumda kullanmaktan daha hızlı geldi (bunun için arama yapmanıza gerek yok basename). Yapıcı yorumlarınız için tekrar teşekkürler.
Simply_Me
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.