Soru Unix'te tekrarlanan hareket programı?


Bazen aynı içeriğe sahip olan ancak senkronizasyondan kurtulmuş iki ağaçım var (çünkü etrafta veya başka bir yere disk taşıdım). İyi bir örnek, Fedora'dan gelen paketlerin aynısını çizdiğim bir ağaç.

Tüm dosyaları ağaç1'den ağaç2'ye taşıyarak yeniden birleştirmek istiyorum.

Genellikle şunu yaparım:

rsync -arv tree1/* tree2

Ardından ağaç1'i silin.

Ancak, bu çok fazla zaman ve disk alanı gerektirir ve yapabilmek çok daha kolay olacaktır:

mv -r tree1/* tree2

Başka bir deyişle, özyinelemeli bir hareket. Daha hızlı olurdu çünkü her şeyden önce kopya bile olmaz, sadece inode'ları hareket ettirir, ikincisi de sonunda bir silmeye gerek duymazdım.

Bu var mı?

Bir test vakası olarak, aşağıdaki komut dizisini göz önünde bulundurun:

$ mkdir -p a/b
$ touch a/b/c1
$ rsync -arv a/ a2
sending incremental file list
created directory
./
b/
b/c1
b/c2

sent 173 bytes  received 57 bytes  460.00 bytes/sec
total size is 0  speedup is 0.00
$ touch a/b/c2

Şimdi hangi komut a / b / c2'yi a2 / b / c2'ye taşıyor ve ardından bir alt ağacı siliyor (çünkü içindeki her şey hedef ağacında zaten var)?


6
2018-06-11 13:24


Menşei


Bu çok güzel bir soru. nerede çalışıyorum ppl bazı karmaşık bash ve awk betikleri kullanarak sorunu çözdüm - biosFF
Tercih edilen verimsiz yaklaşımım cp -R tree1/* tree2 sonra ağaç silme1. - RomanSt


Cevaplar:


Gnu's tarafından mv (1) manpage başına mv:

-u, --update move only when the SOURCE file is newer than the destination file or when the destination file is missing


2
2018-06-11 13:43



Bunun işe yaradığından emin misin? Örneğin; [thomas @ ana ~] $ mkdir -pa / b [thomas @ ana ~] $ dokunmatik a / b / c1 [thomas @ ana ~] $ rsync -arv a a2 artımlı dosya listesi listesi oluşturdu a2 a / a / b / a / b / c1 gönderen 125 bayt 39 bayt 328.00 bayt / sn toplam boyut aldı 0 hızlanma 0.00 [thomas @ ana ~] $ dokunmatik a / b / c2 [thomas @ ana ~] $ mv -ua / * a2 mv: hareket edemiyor a/b' to a2 / b ': Dizin boş değil [thomas @ ana ~] $ mv -u-A a2 mv: hareket edemiyor a' to a2 ': Dizin boş değil - Thomas Vander Stichele


Önerilen mv -uf dir1/* dir2/ Her dosyaya değil, (alt) dizinleri taşıyın. kullanmayı deneyebilirsiniz find

cd dir1
find . -type d -exec mkdir -p dir2/"{}" \;
find . -type f -exec mv -uf "{}" dir2/"{}" \;

Veya benzeri


2
2018-06-11 18:02





Değil

mv -uf tree1/* tree2/

iş?


1
2018-06-11 13:44



Hayır: thomas @ ana ~] $ mv -uf a / * a2 / mv: hareket edemiyor a/b' to a2 / b ': Dizin boş değil - Thomas Vander Stichele
mv: hareket edemiyor includes' to a subdirectory of itself, ../includes '- yani birleşmiyor - RomanSt


Geceyarısı Komutanı (mc) de bu tür şeyler için güzel. CTRL-t ile dosyaları etiketleyin, F6'ya basın ve hedef dosyaların üzerine yazılmasını istediğinde, eski dosyaların üzerine yazmak istiyorsanız Güncelle'yi seçin.


1
2018-06-11 13:52





Cihaz içi taşımacılık için "cp -l & rm" yi kullanabilirsiniz:

cp -alv --backup=numbered tree1/* tree2 &&
rm -rf tree1/
  • -l arasında cp kopyalama yerine sabit bağlantılar kullanmak için (bu aynı zamanda cihazlar arası işlemleri de engeller)
  • --backup=numbered arasında cp Hedef dizindeki mevcut dosyaları yedeklemek için

Ve bu iki konu hakkında dikkatli olun:

  • kullanım && Cihazlar arası hedeflerde yanlışlıkla çalıştırırsanız, temizlenmemiş verilerinizin kaldırılmasını önlemek için. (corss-cihazında cp "durumuyla çıkılıyor"1"En azından GNU coreutils için"
  • "ile başlayan dosyalar"." içinde tree1Varsa onları kaybedersiniz.

1
2017-08-31 02:11



cp bu tür bir şeyde korkunç bir şeydir, çünkü genellikle sabit linkleri / yumuşak bağlantıları yok eder ve bunları tek tek dosyalar ile değiştirir. Benzer şekilde, ACL'leri düz tutmak ve bazen seyrek dosyalar hakkında kafa karıştırmak güvenilir değildir. - chris


Javier'in bulduğu cevabı, orijinal dizinleri kaldırmaması dışında iyi çalışır. Sonuna ekle:

rmdir $(find . -type d  |grep -v ^\.$)

1
2018-06-28 17:09



Howie, ServerFault'a hoş geldiniz! Cevabınız bir başkasının üzerine eklediğinden, yanıtlarına en iyi şekilde yorumda bulunabilirsiniz. Ya da, cevabınızı bu soruya tamamen cevap vermek için düzenleyebilirsiniz. (Sorusu silindiyse, sizinkiler kendi başına kalmalıdır.) - Aaron Copley
Bu, dizin adları beyaz boşluk içeriyorsa başarısız olur. Daha iyi: find . -type d -not -name '.' -delete (veya ! yerine -not) - Dennis Williamson


yanılmak

mv dir1/* dir2/

ya da sadece

rsync -arv --remove-source-files  tree1/* tree2

yeterli olmalı, muhtemelen çok fazla girişin olduğu bir noktada sorun yaşayacaksınız dir1.

find sourcedir -maxdepth 1 -exec echo mv {} targetdir/ \;

güzel bir seçenek olmalı

find sourcedir -maxdepth 1 -print0 |xargs -0 -I _ echo mv _ targetdir
find sourcedir -maxdepth1 -exec mv {} targetdir/ +

her ikisi de gerekli değil çünkü mv sadece 2 seçeneği (kaynak hedef) alıyor, bu yüzden bu durumda çok sayıda süreçle yaşamak zorunda kalacaksınız.


0
2018-06-11 13:44



İstediğim şey bu değil. Çözümünüz sadece bir seviye derinleşiyor ve alt dizinlere girmiyor. - Thomas Vander Stichele
Bu, daha sonraki mv komutuyla bir dizinden daha fazlasını tekrarlamaya gerek olmadığı için tekrarlamaz. Ancak, rsync ile başladığınızdan beri, bildiğiniz araçta sizi koruyacak artı rsync / rm kombinasyonu kadar yer kullanmayacak olan --remove-source-files anahtarını öneririm. - serverhorror
Başka bir notta: sadece birleştirme ile ilgili yazılarınızı okudum çünkü mn -n veya -i seçenekleriyle oynamak isteyebilirsiniz. - serverhorror
Eminim ki ağacın çoğunun hedefte zaten var olduğu gerçeğini düşünmüyorsanız, ilk mv komutunuz çalışmayacaktır. -N veya -i'nin burada ne olduğundan emin olamayacağından emin değilim. Lütfen örneği deneyin. - Thomas Vander Stichele


cd /tree1
mv * /tree2 

Bu gizli dosyaları veya klasörleri taşımaz, ancak orijinal örneğiniz de olmaz.


0
2018-06-12 12:00





Sanırım, mv düşündüğün şeyi yapmıyor.

Bir unix dosya sistemi 3 bileşen içerir:

  • dizin girdileri
  • düğüm
  • bloklar

Bir dizin girişi bir inode'a işaret eder.

Inode, dosya hakkında metatatata sahiptir (bir dosya, dizin, adlandırılmış bir boru mu? Kimin sahibi? İzinleri nelerdir? Bu inode hangi blokları kullanır?

Bloklar, aslında dosyanın içeriğini içeren şeylerdir.

Yani - bir dosyayı "mv" yaptığınızda, gerçekten yaptığınız şey ilk dizin girişinin bağlantısını kesmek ve başka bir yerde yeniden ilişkilendirmektir.

snoopy -> inode 333 
woodstock -> inode 333

Hiçbir veri kopyalanmadı / kopyalanmadı. Bağlantı snoopy oluşturuyorsunuz, daha sonra link woodstock yaratıyorsunuz ve link snoopy'yi siliyorsunuz. (işler genellikle dizinler ile biraz farklıdır, çünkü genellikle hardlinked dizinleri yapamazsınız, ancak "link" ismi sadece değişir).

Ya bir dosya sisteminden diğerine geçiyorsanız? Eski günlerde, mv bir hatayı attı ve dosyayı bir dosya sisteminden diğerine taşıyamayacağınızı açıkça belirtti. Bu günlerde sessizce mv gibi görünüyor kopyalar Veriler daha sonra orijinali siler.

Eski günlerde, verileri bir dosya sisteminden diğerine taşıyamayacağınız için,

tar -cf -. | (cd / yeni / konum && tar -xf -)

sonra eski verileri silersiniz. Katranın kullanılmasının bir sebebi, eski günlerde, cp'nin "bu sembolik bir bağlantı" ve "bu bir zor bağlantı" gibi meta verileri yok etmesiydi ve bunun yerine bu dosyaların yeni kopyalarını normal dosyalar olarak almanızdı. Yine de, bu tür yapıyı korumak için "cp" bayraklarını vermeniz gerekiyor.

Bir dosya sisteminden diğerine olan bir çok veriyi "hareket ettirmekten" kaçınmanın bir yolu yoktur. Yeni bir hareket veya rsync veya katran veya cpio kullanmanız fark etmez.

Ancak, tüm verileri aynı dosya sisteminde tutarsanız, bu:

mv / filesystem-1 / büyük / dizin * / dosya sistemi-1 / big2 /

Bu çok hızlı olacak çünkü sadece dizin girişlerini değiştiriyor ve gerçek bir veriyi hareket ettirmiyor.

Yeni konum ve kaynak konumlarında zaten bir dosya / dizin varsa ne yapmanız gerektiği gibi oyunda başka sorunlar var mı?


0
2018-06-28 17:39





taşımak ve yapmak istediğiniz dizine geçin

tar cf - * | ( cd /target; tar xfp -)

Mv'den daha hızlı ...


-1
2018-06-11 14:11



Sen cp'den daha hızlı mı demiştin? - rkthkr
Daha hızlı mv sadece kaynak ve hedef farklı dosya sistemlerinde ise. - MikeyB
Bu inode'ları hiç hareket ettirmez. - Thomas Vander Stichele