สคริปต์ของคุณมีจุดล้มเหลวหลายจุด ก่อนอื่นrm *.old*
จะใช้globbingเพื่อสร้างรายการไฟล์ที่ตรงกันทั้งหมดและที่สามารถจัดการกับชื่อไฟล์ที่มีช่องว่าง อย่างไรก็ตามสคริปต์ของคุณจะกำหนดตัวแปรให้กับผลลัพธ์แต่ละตัวของ glob และดำเนินการโดยไม่ต้องอ้างถึง ซึ่งจะแตกถ้าชื่อไฟล์ของคุณมีช่องว่าง ตัวอย่างเช่น:
$ ls
'file name with spaces.old.txt' file.old.txt
$ rm *.old.* ## works: both files are deleted
$ touch "file.old.txt" "file name with spaces.old.txt"
$ for i in ./*; do oldfile=$i; rm -v $oldfile; done
rm: cannot remove './file': No such file or directory
rm: cannot remove 'name': No such file or directory
rm: cannot remove 'with': No such file or directory
rm: cannot remove 'spaces.old.txt': No such file or directory
removed './file.old.txt'
อย่างที่คุณเห็นลูปล้มเหลวสำหรับไฟล์ที่มีช่องว่างในชื่อ ในการทำอย่างถูกต้องคุณจะต้องอ้างอิงตัวแปร:
$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'
ปัญหาเดียวกันนี้มีผลกับการใช้งาน$i
สคริปต์ของคุณ คุณควรเสมอพูดตัวแปรของคุณ
ปัญหาที่เป็นไปได้ต่อไปคือการที่คุณดูเหมือนจะคาดหวังว่าตรงกับไฟล์ที่มีนามสกุล*.old.*
.old
มันไม่ได้ มันตรงกับ "0 หรือมากกว่าตัวอักษร" ( *
) จากนั้น a .
และจากนั้น "เก่า" แล้วอีกคนหนึ่ง.
และจากนั้น "0 หรือมากกว่าตัวละครอีกครั้ง" ซึ่งหมายความว่ามันจะไม่ตรงกับสิ่งที่ชอบfile.old
แต่เฉพาะบางอย่างเช่น `file.old.foo:
$ ls
file.old file.old.foo
$ for i in *; do if [[ "$i" == *.old.* ]]; then echo $i; fi; done
file.old.foo
file.old
ดังนั้นไม่ตรงกับศัตรู ไม่ว่าในกรณีใดสคริปต์ของคุณจะซับซ้อนเกินกว่าที่จำเป็น ลองอันนี้แทน:
#!/bin/bash
for i in *; do
if [[ -f "$i" ]]; then
if [[ "$i" == *.old ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i doesn't have an .old extension"
fi
cp -v "$i" "$i".old
else
echo "$i is not a file"
fi
done
โปรดทราบว่าฉันเพิ่มลง-v
ในคำสั่งrm
และ cp which does the same thing as what you were doing with your
echo`
สิ่งนี้ไม่สมบูรณ์ตั้งแต่เมื่อคุณค้นหาตัวอย่างเช่นfile.old
ที่จะถูกลบและในภายหลังสคริปต์จะพยายามคัดลอกและล้มเหลวเนื่องจากไฟล์ไม่มีอยู่อีกต่อไป อย่างไรก็ตามคุณยังไม่ได้อธิบายว่าสคริปต์ของคุณพยายามทำอะไรฉันไม่สามารถแก้ไขได้ถ้าคุณไม่บอกเราว่าคุณพยายามทำอะไรให้สำเร็จ
หากสิ่งที่คุณต้องการคือ i) ลบไฟล์ทั้งหมดที่มี.old
นามสกุลและ ii) เพิ่ม.old
ส่วนขยายไปยังไฟล์ที่มีอยู่ที่ไม่มีมันทั้งหมดที่คุณต้องการคือ:
#!/bin/bash
for i in *.old; do
if [[ -f "$i" ]]; then
rm -v "$i" || echo "rm failed for $i"
else
echo "$i is not a file"
fi
done
## All the ,old files have been removed at this point
## copy the rest
for i in *; do
if [[ -f "$i" ]]; then
## the -v makes cp report copied files
cp -v "$i" "$i".old
fi
done
rm *.old.*
ซึ่งลบไฟล์เหล่านี้ แต่ไม่ใช่ไฟล์ backup.old ฉันกำลังพยายามทำสิ่งนั้นในสคริปต์ของฉัน ขอบคุณ