Sao chép tệp x lần trong shell lệnh


22

Tôi cố gắng sao chép tệp video x lần từ dòng lệnh bằng cách sử dụng vòng lặp for, tôi đã thử nó như thế này, nhưng nó không hoạt động:

for i in {1..100}; do cp test.ogg echo "test$1.ogg"; done

5
Không phải lỗi duy nhất của bạn là echocái không nên có, và cái $1nào nên có $i?
Julie Pelletier

Nếu tôi loại bỏ tiếng vang và chỉ sử dụng test$1.oggthì nó báo: test.ogg và test.ogg là cùng một tệp , vì vậy có vẻ như $ 1 không được nhận ra?
Đen

@EdwardBlack: Nghe có vẻ như tôi hiểu sai yêu cầu của bạn. Giải pháp đó không phù hợp.
cuonglm

@JuliePelletier, chết tiệt, đôi khi điều đó xảy ra với tôi rằng tôi vô tình viết $1thay vì $i, đó là Earlie vào buổi sáng, xin lỗi ... cảm ơn bạn. Tôi sẽ sử dụng $xtrong tương lai thay vì$i
Black

Câu trả lời:


25

Mã shell của bạn có hai vấn đề:

  1. Không echonên ở đó.
  2. Biến $ibị nhập sai như $1trong tên tệp đích.

Để tạo một bản sao của một tệp trong cùng thư mục với chính tệp đó, hãy sử dụng

cp thefile thecopy

Nếu bạn chèn bất cứ thứ gì khác vào đó, vd

cp thefile theotherthing thecopy

sau đó người ta cho rằng bạn muốn sao chép thefiletheotherthingvào thư mục được gọi thecopy.

Trong trường hợp của bạn, nó đặc biệt tìm kiếm một tệp được gọi test.oggvà một tệp có tên echođể sao chép vào thư mục test$1.ogg.

Các $1rất có thể sẽ mở rộng ra một chuỗi rỗng. Đây là lý do tại sao, khi bạn xóa lệnh echokhỏi lệnh, bạn sẽ nhận được "test.ogg và test.ogg là cùng một tệp"; lệnh đang được thực thi về cơ bản là

cp test.ogg test.ogg

Đây có lẽ là một sai lầm.

Cuối cùng, bạn muốn một cái gì đó như thế này:

for i in {1..100}; do cp test.ogg "test$i.ogg"; done

Hoặc, như là một thay thế

i=0
while (( i++ < 100 )); do
  cp test.ogg "test$i.ogg"
done

Hoặc, sử dụng tee:

tee test{1..100}.ogg <test.ogg >/dev/null

Lưu ý: Điều này rất có thể sẽ hoạt động cho 100 bản sao, nhưng đối với hàng ngàn bản sao, nó có thể tạo ra lỗi "danh sách đối số quá dài". Trong trường hợp đó, trở lại sử dụng một vòng lặp.


12

Ngắn gọn và chính xác

< test.ogg tee test{1..100}.ogg

hoặc thậm chí tốt hơn làm

tee test{1..100}.ogg < test.ogg >/dev/null

xem sử dụng lệnh tee để được trợ giúp thêm.

Cập nhật

như được đề xuất bởi @Gilles, việc sử dụng teecó khuyết điểm là không lưu giữ bất kỳ siêu dữ liệu tệp nào. Để khắc phục vấn đề đó, bạn có thể phải chạy lệnh bên dưới sau đó:

cp --attributes-only --preserve Source Target

3
Điều này có khả năng nhanh hơn nhiều cuộc gọi đến cp(phụ thuộc vào kích thước tệp tương ứng với bộ nhớ khả dụng), nhưng có khuyết điểm là không lưu giữ bất kỳ siêu dữ liệu tệp nào.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles ohh, chúng ta có thể vượt qua điều đó?
Raul

3
Bạn có thể chạy cp --attributes-onlysau đó.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles cảm ơn, cập nhật câu trả lời của tôi theo sự giúp đỡ của bạn.
Rahul

FWIW không có câu trả lời nào khác được sử dụng cp -pđể bảo tồn siêu dữ liệu.
roaima


1

Lệnh folowing sẽ sao chép tệp .a 5 lần:

$ seq 5 | xargs -I AA cp file.a fileAA.a

Nếu bạn thích dd (không giống như cp!):

$ seq 5 | xargs -I AA dd if=file.a of=fileAA.a

0

Bạn đã không gọi biến i trong khi sao chép

sử dụng kịch bản dưới đây. Theo thử nghiệm, nó hoạt động tốt

for i in {1..10}; do cp -rvfp test.ogg test$i.ogg ;done

3
Điều này giống như hai câu trả lời trước và một nhận xét ngoại trừ (1) câu hỏi hỏi khoảng 100 và câu trả lời của bạn sử dụng 10, (2) bạn đã thêm các -rvftùy chọn vào một cách không cần thiết cpvà (3) bạn đã không trích dẫn mở rộng biến của mình . (Cũng lưu ý rằng thông thường có khoảng trắng giữa các ký hiệu dấu chấm câu ;và từ sau.) Việc thêm -ptùy chọn là có giá trị, nhưng (4a) nó đã được xử lý (trong các bình luận) và (4b) câu trả lời của bạn không hữu ích nếu bạn không giải thích những gì bạn đang làm.
Scott
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.