Làm cách nào để sao chép một tập tin vào nhiều thư mục bằng dòng lệnh?


67

Tôi đã cố gắng sao chép một tập tin test.txtvào nhiều thư mục bằng một lệnh:

cp ~/test.txt ~/folder1 ~/folder2

Nhưng tôi đã không thành công. Có cách nào để làm điều đó trong một lệnh để tôi có thể sao chép một tập tin hoặc thậm chí một thư mục vào nhiều thư mục không?


Không dễ dàng. Bạn có thể muốn xem xét "rsync" để cập nhật hiệu quả nhiều bản sao hiện có của một thư mục
Thorbjørn Ravn Andersen

3
Hãy thử học một chút bash-script. Nó có thể rất hữu ích:for dest in folder1 folder2; do cp ~/test.txt ~/"$dest"; done
Shahbaz

Không phải là một lệnh duy nhất nhưng có thể chỉ giúp một số người vấp ngã ở đây:cp ~/test.txt ~/folder1 && cp ~/test.txt ~/folder2
Manu Järvinen

Câu trả lời:


71

cpcó thể sao chép từ nhiều nguồn, nhưng không thể sao chép vào nhiều đích. Xem man cpđể biết thêm.

Lệnh bash duy nhất mà tôi biết có thể sao chép / lưu vào nhiều đích là tee.

Bạn có thể sử dụng nó trong trường hợp của bạn như sau:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt

Lưu ý rằng teecũng ghi đầu vào vào đầu ra tiêu chuẩn (thiết bị xuất chuẩn). Vì vậy, nếu bạn không muốn điều này, bạn có thể ngăn chặn nó bằng cách chuyển hướng đầu ra tiêu chuẩn /dev/nullnhư sau:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt >/dev/null

10
Thông minh, đó là gian lận! :)
terdon

5
+1, thông minh! Và nếu bạn cũng sử dụng các >/dev/nulltác phẩm với các tệp nhị phân, mà không làm
hỏng

1
+1 cho bạn, người đàn ông luôn luôn của bạn :), nhưng nếu tôi muốn sao chép một thư mục thì sao?
nux

2
@nux Đừng quên sử dụng -rtùy chọn cptrong trường hợp thư mục
Radu Rădeanu

4
@nux: teekhông giống như các cpbản sao chỉ nội dung của tệp bỏ qua chế độ, quyền sở hữu, dấu thời gian của nó. Để tránh lặp lại tên tệp:f=text.txt; <~/$f tee ~/folder1/$f > ~/folder2/$f
jfs

61

Một cách khác để đạt được một bản sao đến nhiều vị trí là lệnh sau:

find dir1 dir2 -exec cp file.txt {} \;

Nếu dir1 hoặc dir2 có các thư mục con mà bạn không muốn sao chép tệp vào, hãy thêm -maxdepth 0tùy chọn:

find dir1 dir2 -maxdepth 0 -exec cp file.txt {} \;

Lưu ý rằng điều này sẽ ghi đè lên mọi tệp trong dir1dir2với file.txtnội dung của, ngoài việc sao chép nó. Để chỉ sao chép file.txtmà không ảnh hưởng đến các tệp khác trong các thư mục này, hãy bảo findchỉ hành động trên các thư mục:

find dir1 dir2 -type d -exec cp file.txt {} \;

4
Giải pháp tốt đẹp! Có vẻ với tôi hoàn hảo hơn với tee.
Danatela

1
Thật vậy, không có chuyển hướng nào được tham gia và đó vẫn là một lệnh.
Sylvain Pineau

2
@SylvainPineau Trong thực tế có 3: một là findvà hai lần (trong trường hợp này) cp. Không phải nói rằng findcần rất nhiều thời gian.
Radu Rădeanu

3
Nếu định nghĩa của "lệnh" là một cuộc gọi "exec", có thể, nhưng đây là "một lệnh" trong cuốn sách của tôi.
kojiro

2
Tôi tiếp tục quay lại cái này, vì vậy tôi nghĩ rằng tôi nên đưa ra một upvote: D
Jonathan

31

Lệnh

cp ~/test.txt ~/folder1 ~/folder2

cố gắng sao chép hai tập tin ( ~/test.txt~/folder1) đến đích folder2. (Và nếu ~/folder2tồn tại và là một thư mục, bạn sẽ có cảnh báo "bỏ qua thư mục").

Nếu bạn muốn tạo nhiều bản sao của tệp test.txt, bạn phải sử dụng một vòng lặp hoặc nhiều lệnh ...

for i in ~/folder1 ~/folder2; do cp  ~/test.txt $i; done 

(... Và hãy cẩn thận nếu bạn có khoảng trắng được nhúng trong tên tệp, bạn sẽ cần trích dẫn).

Để sao chép toàn bộ thư mục, bạn phải sử dụng -rtùy chọn:

for i in ~/folder1 ~/folder2; do cp -r ~/folder3 $i; done

điều này sẽ tạo ~/folder1/folder3~/folder2/folder3với tất cả các tập tin bao gồm.


1
Đối với người đọc đi qua: Theo thông số kỹ thuật , vòng lặp for là lệnh ghép. Do đó, đây vẫn là một lệnh và đáp ứng tất cả các yêu cầu cho câu hỏi.
kojiro

@nux, tôi không đồng ý sửa. 1) hai thủ đô là sai, ý định của tôi là xen kẽ các lệnh vào cụm từ. 2) dấu chấm lửng là một vấn đề của phong cách; làm ơn hãy để phong cách của tôi vào.
Rmano 13/03/2016

1
ok, tôi xin lỗi người đàn ông, tôi nghĩ rằng nó sẽ nhìn tốt hơn.
nux

trên hệ thống của tôi, nó không lưu thư mục3 dưới dạng ~ / thư mục1 / thư mục3, mà thay vào đó sao chép mọi thứ trong thư mục3 vào thư mục1
alpha_989

23

Bạn có thể tạo tập lệnh trợ giúp hoặc bạn có thể thực hiện với xargsvà chức năng in (trong trường hợp này echo):

echo firstDir secondDir | xargs -n 1 cp test

Điều này sẽ làm cho mỗi thư mục là một đối số cho cphàm, sử dụng tệp thử nghiệm làm tham số.


Đây có lẽ là câu trả lời hay nhất / trực tiếp nhất cho câu hỏi
Bryson S.

7

Sau một thời gian dài tìm kiếm, công việc này cũng giống như một Bùa chú!

for dir in *; do [ -d "$dir" ] && cp /path/file.txt "$dir" ; done

Điều này sẽ sao chép file.txt vào mọi thư mục trong vị trí hiện tại của bạn trong thiết bị đầu cuối.

for dir in *; do [ -d "$dir" ] && cp -rf /path/folder "$dir" ; done

Điều này sẽ sao chép một thư mục vào mọi thư mục con trong vị trí hiện tại của bạn trong thiết bị đầu cuối.

Tôi chia sẻ nó hy vọng nó cũng giúp người khác.


Trong zsh, bạn có thể sử dụng for i in *(/); ...để lặp qua tất cả các thư mục con, vì vậy bạn có thể tránh [ -d ...kiểm tra. Mở rộng toàn cầu là một trong những lý do tôi thích nó hơn bash.
Rmano

bạn có thể mã lại một lần nữa trong một lệnh
nux

1
Trong zsh, lệnh đầu tiên của câu trả lời này có thể được đơn giản hóa như for dir in *(/); do cp /path/file.txt "$dir"; done. Xem zsh.sourceforge.net/Intro/intro_2.html
Rmano

5
Bạn có thể loại bỏ thử nghiệm trong bất kỳ vỏ có nguồn gốc Bourne nào vớifor dir in */;
Henk Langeveld

@nux Điều này hoạt động thực sự tốt và lệnh rất dễ làm theo. Nó nên được bình chọn cao hơn nhiều!
nukeguy

1

Nếu bạn muốn sao chép tệp test.txt trong mọi thư mục trong / tmp / target / ...

tạo môi trường thử nghiệm:

mkdir /tmp/target
cd /tmp/target
mkdir -v {folder1,folder2,folder3}
touch test.txt

sao chép nó:

find * -maxdepth 0 -type d -exec cp -vi test.txt {} \;

0

Chỉ cần suy nghĩ để đưa ra một biến thể cho câu trả lời của Sylvain Pineau

ở đâu dir1dir2không có trong thư mục hiện tại của bạn.

find ./ -maxdepth 2 -type d -name dir1 -exec cp file.txt {} \;

Ở đây find sẽ tìm dir1hai cấp độ sâu hoặc bạn có thể bỏ -maxdepththam số để tìm dir1trong tất cả các thư mục trong thư mục hiện tại và bên dưới nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.