Ada berbagai kemungkinan poin kegagalan dalam skrip Anda. Pertama-tama, rm *.old*
akan menggunakan globbing untuk membuat daftar semua file yang cocok, dan itu bisa berurusan dengan nama file yang mengandung spasi. Namun, skrip Anda memberikan variabel ke setiap hasil glob dan melakukannya tanpa mengutip. Itu akan rusak jika nama file Anda mengandung spasi. Sebagai contoh:
$ 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'
Seperti yang Anda lihat, loop gagal untuk file dengan spasi dalam namanya. Untuk melakukannya dengan benar, Anda perlu mengutip variabel:
$ for i in ./*; do oldfile="$i"; rm -v "$oldfile"; done
removed './file name with spaces.old.txt'
removed './file.old.txt'
Masalah yang sama berlaku untuk hampir setiap penggunaan $i
dalam skrip Anda. Anda harus selalu mengutip variabel Anda .
Masalah berikutnya yang mungkin terjadi adalah Anda sepertinya mengharapkan *.old.*
file yang cocok dengan ekstensi .old
. Tidak. Ini cocok dengan "0 karakter atau lebih" ( *
), lalu a .
, lalu "lama", lalu yang lain .
dan kemudian "0 atau lebih karakter lagi". Ini berarti bahwa itu tidak akan cocok dengan sesuatu seperti file.old
, tetapi hanya sesuatu seperti `file.old.foo:
$ ls
file.old file.old.foo
$ for i in *; do if [[ "$i" == *.old.* ]]; then echo $i; fi; done
file.old.foo
Jadi, tidak ada lawan yang cocok file.old
. Bagaimanapun, skrip Anda jauh lebih kompleks daripada yang dibutuhkan. Coba yang ini sebagai gantinya:
#!/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
Perhatikan bahwa saya menambahkan -v
ke pernyataan rm
dan cp which does the same thing as what you were doing with your
echo`.
Ini tidak sempurna karena ketika Anda menemukan, misalnya, file.old
yang akan dihapus dan, nanti, skrip akan mencoba menyalinnya dan gagal karena file tidak ada lagi. Namun, Anda belum menjelaskan apa yang sebenarnya ingin dilakukan skrip Anda, jadi saya tidak dapat memperbaikinya kecuali Anda memberi tahu kami apa yang sebenarnya ingin Anda capai.
Jika yang Anda inginkan adalah i) menghapus semua file dengan .old
ekstensi dan ii) menambahkan .old
ekstensi ke file yang ada yang tidak memilikinya, yang Anda butuhkan adalah:
#!/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.*
yang menghapus file-file ini tetapi tidak file.old file cadangan. Saya mencoba melakukan itu dalam skrip saya. Terima kasih