Có thể sao chép một tập tin vào nhiều thư mục bằng lệnh cp không?
Tôi đã thử cách sau, không được:
cp file1 /foo/ /bar/
cp file1 {/foo/,/bar}
Tôi biết có thể sử dụng vòng lặp for hoặc tìm. Nhưng nó có thể sử dụng lệnh gnu cp không?
Có thể sao chép một tập tin vào nhiều thư mục bằng lệnh cp không?
Tôi đã thử cách sau, không được:
cp file1 /foo/ /bar/
cp file1 {/foo/,/bar}
Tôi biết có thể sử dụng vòng lặp for hoặc tìm. Nhưng nó có thể sử dụng lệnh gnu cp không?
Câu trả lời:
Không, cp
có thể sao chép nhiều nguồn nhưng sẽ chỉ sao chép vào một đích duy nhất. Bạn cần sắp xếp để gọi cp
nhiều lần - một lần cho mỗi điểm đến - cho những gì bạn muốn làm; sử dụng, như bạn nói, một vòng lặp hoặc một số công cụ khác.
Bạn không thể làm điều này với cp
một mình nhưng bạn có thể kết hợp cp
với xargs
:
echo dir1 dir2 dir3 | xargs -n 1 cp file1
Sẽ sao chép file1
đến dir1
, dir2
và dir3
. xargs
sẽ gọi cp
3 lần để làm điều này, xem trang man xargs
để biết chi tiết.
cp
một mình" Chỉ vì câu trả lời cố gắng hữu ích bằng cách đề xuất một cách khác không có nghĩa là câu hỏi không được trả lời.
echo dir[1-3] | xargs -n 1 cp filename
).
Ký tự đại diện cũng hoạt động với mã Roberts
echo ./fs*/* | xargs -n 1 cp test
Theo như tôi có thể thấy, bạn có thể sử dụng như sau:
ls | xargs -n 1 cp -i file.dat
Các -i
tùy chọn cp
phương tiện lệnh đó bạn sẽ được hỏi có ghi đè lên một tập tin trong thư mục hiện hành với file.dat
. Mặc dù nó không phải là một giải pháp hoàn toàn tự động, nó đã giúp ích cho tôi.
-i
bảo vệ, bạn sẽ không nhắc bạn về việc viết mỗi tệp chứ? thay vì sao chép vào các thư mục?
cp: overwrite
câu hỏi, nhưng tôi không phải trả lời bất kỳ câu hỏi nào và nó không ghi đè lên các tập tin.
Tôi sẽ sử dụng cat
và tee
dựa trên các câu trả lời tôi thấy tại /superuser/32630/pool-file-copy-from-single-source-to-multipl-target thay vì cp
.
Ví dụ:
cat inputfile | tee outfile1 outfile2 > /dev/null
cat <inputfile> | tee /path-to-files/outfile{1..4} > /dev/null
tee < inputfile outfile1 outfile2 > /dev/null
cũng là một mẫu hữu ích như thể hiện trong câu trả lời của Taywee. Lưu ý việc sử dụng chuyển hướng io với '<' để không cần đường ống từ mèo.
Không sử dụng cp mỗi se, nhưng ...
Điều này xuất hiện với tôi trong bối cảnh sao chép rất nhiều cảnh quay của Gopro từ thẻ SD (chậm) sang ba ổ USB (chậm). Tôi muốn đọc dữ liệu chỉ một lần, vì nó mất mãi mãi. Và tôi muốn nó đệ quy.
$ tar cf - src | tee >( cd dest1 ; tar xf - ) >( cd dest2 ; tar xf - ) | ( cd dest3 ; tar xf - )
(Và bạn có thể thêm nhiều phần> () nếu bạn muốn có thêm đầu ra.)
Tôi đã không điểm chuẩn điều đó, nhưng nó chắc chắn nhanh hơn rất nhiều so với cp-in-a-loop (hoặc một loạt các lệnh gọi cp song song).
Để sử dụng sao chép với các xargs
thư mục bằng cách sử dụng ký tự đại diện trên Mac OS, giải pháp duy nhất phù hợp với tôi với các khoảng trắng trong tên thư mục là:
find ./fs*/* -type d -print0 | xargs -0 -n 1 cp test
Trong trường hợp test
là file để sao chép
Và ./fs*/*
các thư mục để sao chép để
Vấn đề là xargs xem các không gian như một đối số mới, các giải pháp để thay đổi ký tự dấu phân cách bằng cách sử dụng -d
hoặc -E
không may làm việc không đúng cách trên Mac OS.
Về cơ bản tương đương với câu trả lời xargs, nhưng trong trường hợp bạn muốn thực thi song song:
parallel -q cp file1 ::: /foo/ /bar/
Vì vậy, ví dụ, để sao chép file1 vào tất cả các thư mục con của thư mục hiện tại (bao gồm cả đệ quy):
parallel -q cp file1 ::: `find -mindepth 1 -type d`
Lưu ý: Điều này có lẽ chỉ chuyển tải bất kỳ mức tăng tốc đáng chú ý nào cho các trường hợp sử dụng rất cụ thể, ví dụ: nếu mỗi thư mục đích là một đĩa riêng biệt.
Nó cũng có chức năng tương tự như đối số '-P' cho xargs.
Không, bạn không thể.
Tôi đã tìm thấy nhiều lần tôi có thể sử dụng chức năng này vì vậy tôi đã tạo ra công cụ của riêng mình để làm điều này cho tôi.
http://github.com/ddavison/branch
khá đơn giản -
branch myfile dir1 dir2 dir3
/e
chẳng hạn, chỉ một lần trên mỗi máy, thì tôi có thể viết các công cụ truyền động của riêng mình và giữ chúng mãi mãi.
Giả sử bạn muốn sao chép fileName.txt
vào tất cả các thư mục con trong thư mục làm việc hiện tại.
Nhận tất cả các tên thư mục con thông qua ls
và lưu chúng vào một số tệp tạm thời,allFolders.txt
ls > allFolders.txt
In danh sách và chuyển nó cho lệnh xargs
.
cat allFolders.txt | xargs -n 1 cp fileName.txt
Một cách khác là sử dụng mèo và tee như sau:
cat <source file> | tee <destination file 1> | tee <destination file 2> [...] > <last destination file>
Tôi nghĩ rằng điều này sẽ khá kém hiệu quả, vì công việc sẽ được phân chia giữa một số quy trình (một cho mỗi đích) và ổ cứng sẽ ghi một số tệp cùng một lúc trên các phần khác nhau của đĩa. Tuy nhiên, nếu bạn muốn ghi một tệp ra nhiều ổ đĩa khác nhau, phương pháp này có thể sẽ khá hiệu quả (vì tất cả các bản sao có thể xảy ra đồng thời).
Sử dụng tập lệnh bash
DESTINATIONPATH[0]="xxx/yyy"
DESTINATIONPATH[1]="aaa/bbb"
..
DESTINATIONPATH[5]="MainLine/USER"
NumberOfDestinations=6
for (( i=0; i<NumberOfDestinations; i++))
do
cp SourcePath/fileName.ext ${DESTINATIONPATH[$i]}
done
exit
Nếu tất cả các thư mục đích của bạn khớp với một biểu thức đường dẫn - như chúng là tất cả các thư mục con của path/to
- thì chỉ cần sử dụng find
kết hợp với cp
như thế này:
find ./path/to/* -type d -exec cp [file name] {} \;
Đó là nó.
find
trong chuỗi.
Điều này sẽ sao chép vào các thư mục con ngay lập tức, nếu bạn muốn đi sâu hơn, điều chỉnh -maxdepth
tham số.
find . -mindepth 1 -maxdepth 1 -type d| xargs -n 1 cp -i index.html
Nếu bạn không muốn sao chép vào tất cả các thư mục, hy vọng bạn có thể lọc các thư mục mà bạn không quan tâm. Ví dụ sao chép vào tất cả các thư mục bắt đầu bằng a
find . -mindepth 1 -maxdepth 1 -type d| grep \/a |xargs -n 1 cp -i index.html
Nếu sao chép vào một tập hợp các thư mục tùy ý / rời rạc, bạn sẽ cần đề xuất của Robert Gamble.
Tôi muốn sao chép một tập tin vào nhiều thư mục như vậy:
cp file1 /foo/; cp file1 /bar/; cp file1 /foo2/; cp file1 /bar2/
Và sao chép một thư mục vào các thư mục khác:
cp -r dir1/ /foo/; cp -r dir1/ /bar/; cp -r dir1/ /foo2/; cp -r dir1/ /bar2/
Tôi biết nó giống như ban hành một số lệnh, nhưng nó hoạt động tốt với tôi khi tôi muốn gõ dòng 1 và bỏ đi một lúc.
Ví dụ: nếu bạn đang ở trong thư mục mẹ của các thư mục đích bạn có thể làm:
cho tôi bằng $ (ls); làm cp nguồnfile $ i; làm xong
ls
và luôn trích dẫn các biến. for i in ./*; do cp sourcefile "$i"; done