ทำซ้ำไฟล์ x ครั้งในคำสั่งเชลล์


22

ฉันพยายามทำซ้ำไฟล์วิดีโอ x ครั้งจากบรรทัดคำสั่งโดยใช้ for for loop ฉันพยายามแบบนี้ แต่มันไม่ทำงาน:

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

5
ไม่ได้เป็นของคุณเพียงข้อผิดพลาดechoที่ไม่ควรจะมีและ$1ที่ควรจะเป็น$i?
Julie Pelletier

ถ้าฉันลบเสียงก้องและใช้งานเท่านั้นtest$1.oggก็บอกว่า: test.ogg และ test.ogg เป็นไฟล์เดียวกันดังนั้นดูเหมือนว่า $ 1 ไม่เป็นที่รู้จัก?
Black

@EdwardBlack: ดูเหมือนฉันเข้าใจผิดความต้องการของคุณ ทางออกนั้นไม่เหมาะสม
cuonglm

@JuliePelletier เอ่อมันบางครั้งก็เกิดขึ้นกับฉันว่าฉันตั้งใจเขียน$1แทน$iมันเป็น earlie ในตอนเช้าขอโทษ ... ขอบคุณ ฉันจะใช้$xในอนาคตแทน$i
Black

คำตอบ:


25

รหัสเชลล์ของคุณมีสองประเด็น:

  1. echoไม่ควรจะมี
  2. ตัวแปร$iถูกพิมพ์ผิดเช่นเดียวกับ$1ในชื่อไฟล์ปลายทาง

ในการทำสำเนาไฟล์ในไดเรกทอรีเดียวกับไฟล์นั้นให้ใช้

cp thefile thecopy

หากคุณใส่อะไรเข้าไปในนั้นเช่น

cp thefile theotherthing thecopy

แล้วมันจะสันนิษฐานว่าคุณต้องการคัดลอกthefileและtheotherthingเข้าไปในไดเรกทอรีthecopyที่เรียกว่า

ในกรณีของคุณมันโดยเฉพาะมองหาไฟล์ที่เรียกว่าtest.oggและเป็นหนึ่งในชื่อที่จะคัดลอกไปยังไดเรกทอรีechotest$1.ogg

$1ส่วนใหญ่มีแนวโน้มที่จะขยายไปยังสตริงที่ว่างเปล่า นี่คือเหตุผลที่เมื่อคุณลบechoคำสั่งจากคำสั่งคุณจะได้รับ "test.ogg และ test.ogg เป็นไฟล์เดียวกัน"; คำสั่งที่ถูกดำเนินการเป็นหลัก

cp test.ogg test.ogg

นี่อาจเป็นสิ่งที่พิมพ์ผิด

ในท้ายที่สุดคุณต้องการสิ่งนี้:

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

หรือเป็นทางเลือก

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

หรือใช้tee:

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

หมายเหตุ: อาจเป็นไปได้สำหรับ 100 สำเนา แต่สำหรับหลายพันสำเนามันอาจสร้างข้อผิดพลาด "รายการอาร์กิวเมนต์ยาวเกินไป" ในกรณีนั้นให้กลับไปใช้การวนซ้ำ


12

สั้นและแม่นยำ

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

หรือดีกว่าทำ

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

ดูการใช้คำสั่ง teeเพื่อขอความช่วยเหลือเพิ่มเติม

ปรับปรุง

ตามที่แนะนำโดย @Gilles การใช้teeมีข้อบกพร่องที่จะไม่รักษาข้อมูลเมตาของไฟล์ไว้ เพื่อเอาชนะปัญหานั้นคุณอาจต้องเรียกใช้คำสั่งด้านล่างหลังจากนั้น:

cp --attributes-only --preserve Source Target

3
สิ่งนี้อาจเร็วกว่าการโทรหลายครั้งcp(ขึ้นอยู่กับขนาดไฟล์ที่สัมพันธ์กับหน่วยความจำที่มีอยู่) แต่มีข้อบกพร่องที่จะไม่เก็บข้อมูลเมตาของไฟล์ไว้
Gilles 'หยุดความชั่วร้าย'

@Gilles Ohh เราสามารถเอาชนะมันได้หรือไม่
ราหุล

3
คุณสามารถเรียกใช้cp --attributes-onlyหลังจากนั้น
Gilles 'หยุดความชั่วร้าย'

@Gilles ขอบคุณอัปเดตคำตอบของฉันตามความช่วยเหลือของคุณ
ราหุล

FWIW ไม่มีคำตอบอื่นใดที่ใช้cp -pในการรักษาข้อมูลเมตา
roaima


1

คำสั่ง folowing จะคัดลอกไฟล์. 5 ครั้ง:

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

หากคุณต้องการ dd (ไม่ใช่ cp!):

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

0

คุณยังไม่ได้เรียกตัวแปร i ในขณะที่คัดลอก

ใช้สคริปต์ด้านล่าง เมื่อทดสอบแล้วก็ใช้งานได้ดี

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

3
นี่เป็นคำตอบเดียวกับสองคำตอบก่อนหน้านี้และความคิดเห็นยกเว้น (1) คำถามถามเกี่ยวกับ 100 และคำตอบของคุณใช้ 10, (2) คุณได้เพิ่ม-rvfตัวเลือกโดยไม่จำเป็นcpและ (3) คุณไม่สามารถอ้างถึงการขยายตัวแปร . (โปรดทราบว่าเป็นเรื่องธรรมดาที่จะมีช่องว่างระหว่างสัญลักษณ์เครื่องหมายวรรคตอนเช่น;และคำต่อไปนี้) การเพิ่ม-pตัวเลือกมีค่า แต่ (4a) ได้รับการแก้ไขแล้ว (ในความคิดเห็น) และ (4b) คำตอบของคุณไม่ใช่ มีประโยชน์ถ้าคุณไม่อธิบายสิ่งที่คุณกำลังทำ
สกอตต์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.