Gandakan file x kali dalam shell perintah

22

Saya mencoba menduplikasi file video x kali dari baris perintah dengan menggunakan for loop, saya sudah mencobanya seperti ini, tetapi tidak berhasil:

for i in {1..100}; do cp test.ogg echo "test$1.ogg"; done
Hitam
sumber
5
Bukankah satu-satunya kesalahan Anda echoyang seharusnya tidak ada, dan $1yang seharusnya $i?
Julie Pelletier
jika saya menghapus gema dan hanya menggunakan test$1.oggmaka dikatakan: test.ogg dan test.ogg adalah file yang sama , jadi sepertinya $ 1 tidak dikenali?
Hitam
@ EdwardBlack: Kedengarannya saya salah mengerti kebutuhan Anda. Solusi itu tidak cocok.
cuonglm
@JuliePelletier, sial, kadang-kadang terjadi pada saya bahwa saya tidak sengaja menulis, $1bukan $iawal pagi, maaf ... terima kasih. Saya akan menggunakan $xdi masa depan sebagai ganti$i
Black

Jawaban:

25

Kode shell Anda memiliki dua masalah:

  1. The echoseharusnya tidak ada.
  2. Variabel $isalah ketik seperti $1dalam nama file tujuan.

Untuk membuat salinan file di direktori yang sama dengan file itu sendiri, gunakan

cp thefile thecopy

Jika Anda memasukkan hal lain di sana, mis

cp thefile theotherthing thecopy

maka diasumsikan bahwa Anda ingin menyalin thefiledan theotherthingmasuk ke direktori yang disebut thecopy.

Dalam kasus Anda, ini secara khusus mencari file yang dipanggil test.oggdan satu bernama echountuk menyalin ke direktori test$1.ogg.

The $1kemungkinan besar akan memperluas ke string kosong. Inilah sebabnya, ketika Anda menghapus echodari perintah, Anda mendapatkan "test.ogg dan test.ogg adalah file yang sama"; perintah yang dieksekusi pada dasarnya

cp test.ogg test.ogg

Ini mungkin salah ketik.

Pada akhirnya, Anda menginginkan sesuatu seperti ini:

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

Atau, sebagai alternatif

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

Atau, menggunakan tee:

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

Catatan: Ini kemungkinan besar akan berfungsi untuk 100 salinan, tetapi untuk ribuan salinan mungkin menghasilkan kesalahan "daftar argumen terlalu lama". Dalam hal ini, kembali menggunakan loop.

Kusalananda
sumber
12

Singkat dan tepat

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

atau bahkan lebih baik

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

lihat penggunaan perintah tee untuk bantuan lebih lanjut.

Memperbarui

seperti yang disarankan oleh @Gilles, menggunakan teememiliki cacat tidak menjaga metadata file apa pun. Untuk mengatasi masalah itu, Anda mungkin harus menjalankan perintah di bawah ini setelah itu:

cp --attributes-only --preserve Source Target
Rahul
sumber
3
Ini berpotensi lebih cepat dari beberapa panggilan ke cp(tergantung pada ukuran file relatif terhadap memori yang tersedia), tetapi memiliki cacat tidak menjaga metadata file apa pun.
Gilles 'SO- berhenti menjadi jahat'
@Gilles ohh, bisakah kita mengatasinya?
Rahul
3
Anda bisa berlari cp --attributes-onlysesudahnya.
Gilles 'SO- berhenti menjadi jahat'
@Gilles terima kasih, perbarui jawaban saya sesuai bantuan Anda.
Rahul
FWIW tidak ada jawaban lain yang digunakan cp -puntuk mempertahankan metadata juga.
roaima
11
for i in {1..100}; do cp test.ogg "test_$i.ogg" ; done
coffeMug
sumber
1
Perluasan variabel harus dikutip.
kucing
1

Perintah berikut akan menyalin file.a 5 kali:

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

Jika Anda lebih suka dd (tidak sama dengan cp!):

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

Anda belum memanggil variabel i saat menyalin

gunakan skrip di bawah ini. Saat diuji ternyata bekerja dengan baik

for i in {1..10}; do cp -rvfp test.ogg test$i.ogg ;done
Praveen Kumar BS
sumber
3
Ini sama dengan dua jawaban sebelumnya dan komentar, kecuali (1) pertanyaannya sekitar 100, dan jawaban Anda menggunakan 10, (2) Anda tidak perlu menambahkan -rvfopsi cp, dan (3) Anda gagal mengutip ekspansi variabel Anda . (Perhatikan juga bahwa memiliki spasi antara simbol tanda baca seperti ;dan kata berikut ini merupakan hal yang konvensional .) Penambahan -popsi bernilai, tetapi (4a) sudah dialamatkan (dalam komentar), dan (4b) jawaban Anda tidak membantu jika Anda tidak menjelaskan apa yang Anda lakukan.
Scott