Câu trả lời:
Đối với các tệp đơn lẻ, bạn có thể sử dụng tee
để sao chép vào nhiều nơi:
cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>
hoặc nếu bạn thích phiên bản chưa được chỉnh sửa:
tee <outfile1> <outfile2> > <outfile3> < <inputfile>
Lưu ý rằng như Dennis chỉ ra trong các tee
đầu ra nhận xét stdout
cũng như các tệp được liệt kê, do đó sử dụng chuyển hướng để trỏ đến tệp 3 trong các ví dụ trên. Bạn cũng có thể chuyển hướng này sang /dev/null
bên dưới - điều này có lợi thế là giữ danh sách tệp nhất quán hơn trên dòng lệnh (điều này có thể giúp dễ dàng tạo ra một giải pháp cho số lượng tệp biến đổi) nhưng kém hiệu quả hơn một chút (mặc dù sự khác biệt về hiệu quả là nhỏ: gần giống với sự khác biệt giữa việc sử dụng cat
phiên bản hoặc phiên bản không có cat
):
cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null
Bạn có thể có thể kết hợp một trong những điều trên với find
khá dễ dàng để hoạt động trên nhiều tệp trong một thư mục và ít dễ dàng hơn để hoạt động trên các tệp trải trên một cấu trúc thư mục. Mặt khác, bạn có thể phải đặt song song nhiều thao tác sao chép thành các tác vụ riêng biệt và hy vọng rằng bộ đệm đĩa hệ điều hành sáng và / hoặc đủ lớn để mỗi tác vụ song song được sử dụng lưu trữ dữ liệu được đọc từ bộ nhớ đầu tiên thay vì gây ra ổ đĩa đập phá.
SAILN SÀNG: tee
thường có sẵn trên các thiết lập Linux tiêu chuẩn và các hệ thống unix hoặc unix giống nhau khác, thường là một phần của gói "coreutils" GNU. Nếu bạn đang sử dụng Windows (câu hỏi của bạn không chỉ định) thì bạn nên tìm thấy nó trong các cổng Windows khác nhau như Cygwin.
THÔNG TIN TIẾN ĐỘ: Khi sao chép một tệp lớn khỏi phương tiện quang có thể mất một thời gian (hoặc qua mạng chậm hoặc tệp thậm chí lớn hơn từ phương tiện nhanh cục bộ), thông tin tiến trình có thể hữu ích. Trên dòng lệnh, tôi có xu hướng sử dụng trình xem ống (có sẵn trong hầu hết các bản phân phối Linux & nhiều bộ sưu tập cổng Windows và dễ dàng tự biên dịch ở nơi không có sẵn trực tiếp) cho việc này - chỉ cần thay thế cat
bằng pv
:
pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
tee
cũng sẽ xuất ra thiết bị xuất chuẩn, vì vậy bạn có thể muốn thực hiện tee outputfile1 outputfile2 < inputfile > /dev/null
vì việc xuất tệp nhị phân sang thiết bị đầu cuối có thể gây ồn và lộn xộn với cài đặt của nó.
tar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
Cho cửa sổ:
n2ncopy sẽ làm điều này:
Đối với Linux:
Các cp
lệnh một mình có thể sao chép từ nhiều nguồn khác nhau nhưng tiếc là không nhiều điểm đến. Bạn sẽ cần phải chạy nó nhiều lần trong một vòng lặp nào đó. Bạn có thể sử dụng một vòng lặp như vậy và đặt tất cả các tên thư mục trong một tệp:
OLDIFS=$IFS
IFS=$'\n'
for line in $(cat file.txt):
do
cp file $line
done
IFS=$OLDIFS
hoặc sử dụng xargs:
echo dir1 dir2 dir3 | xargs -n 1 cp file1
Cả hai sẽ cho phép bạn sao chép toàn bộ thư mục / nhiều tập tin. Điều này cũng được thảo luận trong này bài viết StackOverflow.
Dựa trên câu trả lời cho một câu hỏi tương tự Một cách khác là sử dụng GNU Parallel để chạy nhiều cp
trường hợp cùng một lúc:
parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3
Lệnh trên sẽ sao chép file1 vào cả ba thư mục đích song song
Trong bash (Linux, Mac hoặc Cygwin):
cat source | tee target1 target2 >targetN
(tee sao chép đầu vào của STDOUT, vì vậy hãy sử dụng chuyển hướng vào mục tiêu cuối cùng).
Trong Windows, Cygwin thường quá mức cần thiết. Thay vào đó, bạn chỉ có thể thêm exes từ dự án UnxUtils , bao gồm mèo, tee và nhiều thứ khác.
Giải pháp của Ryan Thompson:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
rất có ý nghĩa: Nếu tốc độ ghi của các thư mục đích xấp xỉ như nhau thì srcfile sẽ chỉ được đọc một lần từ đĩa. Thời gian còn lại nó sẽ được đọc từ bộ đệm.
Tôi sẽ làm cho nó chung chung hơn một chút, vì vậy bạn cũng nhận được các thư mục con:
for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;
Nếu tốc độ ghi của các dir dir rất khác nhau (ví dụ: một cái nằm trên đĩa ram và cái kia trên NFS), thì bạn có thể thấy rằng các phần của srcdir đọc trong khi sao chép srcdir sang Dest1 không còn trong bộ đệm của đĩa khi ghi mệnh2.
Theo câu trả lời này: /superuser//a/1064516/702806
Một giải pháp tốt hơn là sử dụng tar
và tee
. Lệnh phức tạp hơn nhưng tar
dường như rất mạnh để chuyển VÀ nó cần đọc nguồn chỉ một lần.
tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null
Để sử dụng nó trong tập lệnh, bạn có thể cần khởi chạy tập lệnh của mình với bash -x script.sh
tar
là nó sẽ tự động sao chép (bảo toàn) các thuộc tính tệp (ví dụ: ngày / giờ sửa đổi, chế độ (bảo vệ) và có khả năng ACL, chủ sở hữu / nhóm (nếu được đặc quyền), SELinux bối cảnh (nếu có thể), các thuộc tính mở rộng (nếu có), v.v.) Vòng tay bị lỗi ở PS PS Tại sao người dùng cần sử dụng bash -x
?
#!/bin/sh
ở đầu tập lệnh của mình nhưng cú pháp của lệnh không được chấp nhận. Bạn có thể sử dụng bash -x
hoặc #!/bin/bash
ở đầu tập tin của bạn. Tôi không biết tại sao có sự khác biệt giữa sh
và bash
diễn giải.
Trong bash:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
Nếu bạn muốn làm điều này trong Windows từ PowerShell, thì không thể theo mặc định, vì không giống như -Path
đối số, -Destination
không có nhiều đối số. Tuy nhiên, bạn có thể sử dụng -Passthrough
và xâu chuỗi các lệnh. (Nhưng điều đó không vui chút nào.)
Giải pháp tốt nhất là làm cho riêng bạn, như được hiển thị ở đây .