Salinan file paralel dari satu sumber ke beberapa target?

14

Saya memiliki beberapa file besar di media optik yang ingin saya salin ke beberapa target - dalam hal ini saya memiliki dua hard drive yang terpasang pada komputer yang sama. Apakah ada utilitas yang dapat berfungsi seperti:

copy source target1 target2 ... targetN
Goyuix
sumber

Jawaban:

22

Untuk file tunggal yang dapat Anda gunakan teeuntuk menyalin ke beberapa tempat:

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

atau jika Anda lebih suka versi demoggified:

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

Perhatikan bahwa seperti yang ditunjukkan oleh Dennis dalam teeoutput komentar ke stdoutserta file yang terdaftar, maka gunakan redirect untuk menunjuk ke file 3 dalam contoh di atas. Anda juga dapat mengarahkan ini ke /dev/nullseperti di bawah ini - ini memiliki keuntungan menjaga agar daftar file lebih konsisten pada baris perintah (yang mungkin membuatnya lebih mudah untuk menyusun solusi untuk jumlah variabel file) tetapi sedikit kurang efisien (meskipun perbedaan efisiensi kecil: hampir sama dengan perbedaan antara menggunakan catversi atau versi tanpa cat):

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

Anda mungkin dapat menggabungkan salah satu di atas dengan findcukup mudah untuk beroperasi pada banyak file dalam satu direktori dan kurang mudah untuk beroperasi pada file yang tersebar di suatu struktur direktori. Kalau tidak, Anda mungkin hanya perlu mengatur beberapa operasi penyalinan secara paralel sebagai tugas terpisah dan berharap bahwa cache disk OS cerah dan / atau cukup besar sehingga masing-masing tugas paralel yang digunakan cache membaca data dari yang pertama alih-alih menyebabkan drive-head labrakan.

KETERSEDIAAN: teebiasanya tersedia pada pengaturan Linux standar dan sistem unix atau tidak serupa lainnya, biasanya sebagai bagian dari paket "coreutils" GNU. Jika Anda menggunakan Windows (pertanyaan Anda tidak menentukan) maka Anda harus menemukannya di berbagai port Windows seperti Cygwin.

INFORMASI KEMAJUAN: Karena menyalin file besar dari media optik mungkin memerlukan waktu (atau melalui jaringan lambat, atau file yang lebih besar dari media cepat lokal), informasi kemajuan dapat berguna. Pada baris perintah saya cenderung menggunakan penampil pipa (tersedia di sebagian besar distro Linux & banyak koleksi port Windows dan mudah untuk mengkompilasi sendiri di mana tidak tersedia secara langsung) untuk ini - cukup ganti catdengan pvseperti:

pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
David Spillett
sumber
Saya menemukan tee.exe menjadi bagian dari paket UnxUtils. Terima kasih atas tipnya!
Goyuix
5
Catatan yang teejuga akan ditampilkan ke stdout, jadi Anda mungkin ingin melakukannya tee outputfile1 outputfile2 < inputfile > /dev/nullkarena mengeluarkan file biner ke terminal bisa berisik dan mengacaukan pengaturannya.
Dennis Williamson
Untuk direktori dan banyak file gunakan saja tar bukan cat. Misalnyatar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
CR.
5

Untuk Windows:

n2ncopy akan melakukan ini:

teks alternatif

Untuk Linux:

The cpperintah sendiri dapat menyalin dari berbagai sumber tapi sayangnya tidak banyak tujuan. Anda harus menjalankannya beberapa kali dalam satu lingkaran. Anda dapat menggunakan loop seperti itu dan menempatkan semua nama direktori dalam file:

OLDIFS=$IFS
IFS=$'\n'

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

IFS=$OLDIFS

atau gunakan xargs:

echo dir1 dir2 dir3 | xargs -n 1 cp file1

Kedua hal ini akan memungkinkan Anda untuk menyalin seluruh direktori / banyak file. Hal ini juga dibahas dalam ini artikel StackOverflow.

John T
sumber
Tautan N2NCopy tampaknya rusak.
Wesley
1
Google Fu - sourceforge.net/projects/n2ncopy
Nama Palsu
4

Didasarkan pada jawaban yang diberikan untuk pertanyaan serupa Cara lain adalah dengan menggunakan GNU Parallel untuk menjalankan beberapa cpinstance sekaligus:

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

Perintah di atas akan menyalin file1 ke ketiga folder tujuan secara paralel

rmiesen
sumber
2

Di bash (Linux, Mac atau Cygwin):

cat source | tee target1 target2 >targetN

(tee menyalin inputnya ke STDOUT, jadi gunakan pengalihan pada target terakhir).

Di Windows, Cygwin sering berlebihan. Sebagai gantinya, Anda bisa menambahkan ongkos dari proyek UnxUtils , yang mencakup cat, tee, dan banyak lainnya.

mivk
sumber
1

Solusi Ryan Thompson:

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

masuk akal: Jika kecepatan tulis dir tujuan kurang lebih sama maka srcfile hanya akan dibaca sekali dari disk. Sisa waktu itu akan dibaca dari cache.

Saya akan membuatnya sedikit lebih umum, sehingga Anda juga mendapatkan subdirs:

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

Jika kecepatan tulis dari direktori dir sangat berbeda (misalnya satu di ram disk dan yang lain di NFS), maka Anda dapat melihat bahwa bagian-bagian srcdir membaca saat menyalin srcdir ke dest1 tidak lagi dalam cache disk saat menulis dest2.

Ole Tange
sumber
1

Menurut jawaban ini: https://superuser.com/a/1064516/702806

Solusi yang lebih baik adalah menggunakan tardan tee. Perintahnya lebih rumit tetapi tartampaknya sangat kuat untuk ditransfer DAN perlu membaca sumbernya sekali saja.

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

Untuk menggunakannya dalam skrip, Anda mungkin perlu meluncurkan skrip Anda bash -x script.sh

Rémi Girard
sumber
Lucu. Saya pikir "ini masuk akal, punya upvote". Terpilih. Kemudian saya memeriksa tautannya ...: D
Kamil Maciorowski
Ini jelas lebih unggul daripada jawaban David Spillett (diterima) jika Anda menyalin beberapa file sekaligus. Untuk file sumber tunggal, satu-satunya keuntungan yang dapat saya lihat taradalah menambahkannya secara otomatis akan menyalin (mempertahankan) atribut file (misalnya, tanggal modifikasi / waktu, mode (perlindungan) dan berpotensi ACL, pemilik / grup (jika diistimewakan), SELinux konteks (jika berlaku), atribut diperluas (jika berlaku), dll.) ... ... ... ... ... ... ... PS Mengapa pengguna harus menggunakan bash -x?
Scott
Saya menggunakan #!/bin/shdi awal skrip saya tetapi sintaks dari perintah tidak diterima. Anda dapat menggunakan bash -xatau #!/bin/bashdi awal file Anda. Saya tidak tahu mengapa ada perbedaan antara shdan bashinterpretasi.
Rémi Girard
Kamil Maciorowski - Saya tidak tahu mengapa jawaban Anda tidak dibatalkan. Ini adalah solusi sempurna. Saya ingin membagikannya.
Rémi Girard
0

Dalam bash:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
Ryan Thompson
sumber
2
Saya tidak berpikir ini akan bekerja dengan baik. dalam salinan paralel yang ideal Anda akan membaca sekali, menulis berkali-kali. Saya pikir ini akan melakukan 1: 1 membaca: menulis. mungkin jika salinannya mulai cukup cepat dan drive cache cukup besar Anda sebenarnya tidak perlu mencari kepala baca.
quack quixote