Tek kaynaktan birden çok hedefe paralel dosya kopyalama?


15

Optik medyada birden fazla hedefe kopyalamak istediğim birkaç büyük dosyam var - bu durumda aynı bilgisayara bağlı iki sabit sürücüm var. Gibi işlevler bir yardımcı program var mı:

copy source target1 target2 ... targetN

Yanıtlar:


23

Tek dosyalar teeiçin birden çok yere kopyalamak için kullanabilirsiniz :

cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>

veya demoggified sürümü tercih ederseniz:

tee <outfile1> <outfile2> > <outfile3> < <inputfile>

Not o Dennis yorumlardaki işaret ettiği gibi teehiç çıkışları stdoutyanı sıra sıralanan dosyalar, dolayısıyla yukarıdaki örneklerde dosyaya 3'e noktaya yönlendirmeyi kullanan. Bunu aşağıdaki şekilde de yönlendirebilirsiniz /dev/null- bu, dosya listesini komut satırında daha tutarlı tutma avantajına sahiptir (bu, değişken sayıda dosya için bir çözüm yazmayı kolaylaştırabilir) ancak biraz daha az verimlidir ( verimlilik farkı küçüktür: catsürümü veya sürümü kullanmama arasındaki farkla aynıdır cat):

cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null

Muhtemelen yukarıdakilerden birini, findbir dizinde birden çok dosyada çalışmak için ve bir dizin yapısına yayılmış dosyalar üzerinde çalışmak için daha az kolayca birleştirebilirsiniz. Aksi takdirde, birden fazla kopyalama işlemini ayrı görevler olarak paralel olarak ayarlamanız ve OS disk önbelleğinin kullanılan ve paralel görevlerin her birinin sürücü kafasına neden olmak yerine önbelleğe alınmış okuma verilerinin ilkinden yeterince büyük olmasını ummanız gerekebilir. dayak.

KULLANILABİLİRLİK: teeGenellikle GNU "coreutils" paketinin bir parçası olarak standart Linux kurulumlarında ve diğer unix veya unix benzeri sistemlerde bulunur. Windows kullanıyorsanız (sorunuz belirtmez), Cygwin gibi çeşitli Windows bağlantı noktalarında bulmalısınız.

İLERLEME BİLGİSİ: Büyük bir dosyayı optik medyadan kopyalamak biraz zaman alabileceğinden (veya yavaş ağ üzerinden veya yerel hızlı medyadan bile daha büyük bir dosya), ilerleme bilgileri yararlı olabilir. Komut satırında ben kullanma eğiliminde boru görüntüleyici bunun için (burada mevcut değil doğrudan sizin derlemeye çoğu Linux dağıtımlarının & birçok Windows liman koleksiyonları ve kolay kullanılabilir) - sadece değiştirin catile pvşöyle:

pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>

Tee.exe UnxUtils paketinin bir parçası olarak buldum. Harika ipucu için teşekkürler!
Goyuix

5
teeBunun ayrıca stdout'a da çıkacağını unutmayın , bu nedenle tee outputfile1 outputfile2 < inputfile > /dev/nullterminale bir ikili dosya çıktısının gürültülü ve ayarları ile karışıklık yapabileceğinden yapmak isteyebilirsiniz .
sonraki duyuruya kadar duraklatıldı.

Dizinler ve birden çok dosya için cat yerine tar kullanın. Örneğintar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
CR.

5

Pencereler için:

n2ncopy bunu yapacak:

alternatif metin

Linux için:

cpKomut yalnız birden fazla kaynaktan ama maalesef katı değil hedeflerden kopyalayabilirsiniz. Bir tür döngü halinde birden çok kez çalıştırmanız gerekecektir. Bunun gibi bir döngü kullanabilir ve tüm dizin adlarını bir dosyaya yerleştirebilirsiniz:

OLDIFS=$IFS
IFS=$'\n'

for line in $(cat file.txt):
do
   cp file $line
done

IFS=$OLDIFS

veya xargs kullanın:

echo dir1 dir2 dir3 | xargs -n 1 cp file1

Bunların her ikisi de tüm dizinleri / birden çok dosyayı kopyalamanızı sağlar. Bu, bu StackOverflow makalesinde de ele alınmıştır .


N2CKopya bağlantı kopmuş gibi görünüyor.
Wesley


4

Benzer bir soru için verilen cevaba dayanarak Başka bir yol, aynı anda birden çok örneği çalıştırmak için GNU Paralel kullanmaktır cp:

parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3

Yukarıdaki komut file1 öğesini üç hedef klasöre paralel olarak kopyalayacaktır


2

Bash'da (Linux, Mac veya Cygwin):

cat source | tee target1 target2 >targetN

(tee girdisini STDOUT'a kopyalar, bu nedenle son hedefte yeniden yönlendirmeyi kullanın).

Windows'da Cygwin genellikle aşırıya kaçar. Bunun yerine, exx'leri cat, tee ve daha fazlasını içeren UnxUtils projesinden ekleyebilirsiniz .


1

Ryan Thompson'un çözümü:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;

çok mantıklı: Hedef dizinlerin yazma hızı yaklaşık olarak aynı ise, srcfile diskten yalnızca bir kez okunur. Geri kalan süre önbellekten okunacaktır.

Biraz daha genel yapardım, böylece alt dizinleri de alırsınız:

for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;

Hedef dizinlerin yazma hızı çok farklıysa (örneğin biri ram diskinde, diğeri NFS'de ise), srcdir'i dest1'e kopyalarken srcdir'in okunan bölümlerinin artık disk önbelleğinde yazılmadığını görebilirsiniz. dest2.


1

Bu cevaba göre: /superuser//a/1064516/702806

Daha iyi bir çözüm kullanmaktır tarve tee. Komut daha karmaşık ancak taraktarım için çok güçlü görünüyor ve kaynağı sadece bir kez okuması gerekiyor.

tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null

Bir komut dosyasında kullanmak için, komut dosyanızı bash -x script.sh


Komik. "Bu bir anlam ifade ediyor, bir çıkarım var" diye düşündüm. Upvoted. Sonra bağlantıyı kontrol ettim…: D
Kamil Maciorowski

Aynı anda birden fazla dosya kopyalıyorsanız , bu, David Spillett'in (kabul edilen) cevabından oldukça açıktır . Tek bir kaynak dosya için, eklemenin görebildiğim tek avantajı tar, dosya özniteliklerini (örneğin, değişiklik tarihi / saati, (koruma) modu ve potansiyel olarak ACL'leri, sahip / grup (ayrıcalıklıysa), SELinux'u otomatik olarak kopyalayacağı (koruyacağı) bağlam (varsa), genişletilmiş özellikler (varsa) vb.)……………… PS Not Kullanıcının neden kullanması gerekir bash -x?
Scott

#!/bin/shKomut dosyamın başında kullandım ama komutun sözdizimi kabul edilmedi. Dosyanızın başında bash -xveya #!/bin/bashbaşında kullanabilirsiniz . Arasında bir fark var neden bilmiyorum shve bashyorumların.
Rémi Girard

Kamil Maciorowski - Cevabınızın neden yükseltilmediğini bilmiyorum. Mükemmel bir çözümdür. Paylaşmak istedim.
Rémi Girard

0

Bash'da:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;

2
Bunun iyi performans göstereceğini sanmıyorum. ideal olarak paralel bir kopyada bir kez okur ve birçok kez yazarsınız. bence bu 1: 1 okur: yazar. kopyalar yeterince hızlı başlıyor ve önbellek yeterince büyükse, okuma kafalarını aramanıza gerek kalmayabilir.
quack quixote

0

Bunu Windows'ta PowerShell'den yapmak istiyorsanız, varsayılan olarak mümkün değildir, çünkü -Pathbağımsız değişkenin aksine, -Destinationbirden fazla bağımsız değişken almaz. Ancak, -Passthroughkomutları kullanabilir ve papatya dizimi yapabilirsiniz . (Ama bu eğlenceli değil.)

En iyi çözüm, burada gösterildiği gibi kendiniz yapmaktır .

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.