Saya menulis sebuah skrip untuk memindahkan beberapa file dari satu folder ke folder lain, tetapi saya mendapatkan kesalahan berikut, saya memeriksa 2 folder dan melihat 1 folder ada file seperti itu dan yang lain tidak ada file seperti itu, tetapi mengapa semuanya menunjukkan "mv tidak dapat membuat stat Tidak ada file atau direktori "
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.42.17.124_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/195.113.161.13_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.199.61.205_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.51.218.235_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/213.73.40.105_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/41.225.7.4_tcp.folder/data/*': No such file or directory
mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/83.230.127.122_tcp.folder/data/*': No such file or directory
[esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/
[esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/
129.88.70.226 132.187.230.1 138.96.116.22 155.185.54.250 192.38.109.144 193.136.227.163 193.175.135.61 195.113.161.13 83.230.127.122
130.104.72.200 132.227.62.122 147.83.29.232 156.17.10.52 192.42.43.22 193.137.173.218 193.205.215.74 212.199.61.205
131.130.69.164 132.252.152.194 148.81.140.193 157.181.175.249 192.43.193.71 193.144.21.131 193.226.19.30 212.51.218.235
131.188.44.102 134.151.255.180 152.66.245.162 160.78.253.31 193.1.170.136 193.145.46.243 194.199.68.165 213.73.40.105
131.254.208.10 138.48.3.203 152.81.47.4 192.114.4.3 193.136.166.56 193.166.160.98 194.42.17.124 41.225.7.4
skripnya adalah:
list=`ls dest_folder`
cd dest_folder
cwd=`pwd`
for folder in $list;do
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
done
Saya menjalankannya /home/esolve/project/capture/tcp_50x50/
-r
kemv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
?-r
pilihan untukmv
Jawaban:
Kutipan (
'
) di sana mencegah shell dari melakukan globbing. The*
sedang berlalu harfiah kemv
perintah, yang gagal karena tidak menemukan file yang disebut*
dalam direktori ditunjukkan.Ubah ini menjadi:
(Kutipan ganda untuk mencegah masalah jika Anda memiliki nama direktori dengan spasi di dalamnya. Di
*
luar tanda kutip.)Anda masih akan mendapatkan kesalahan untuk direktori kosong. (Alasan yang sama: jika file tidak menemukan kecocokan untuk pola, itu melewati pola itu sendiri sebagai argumen ke perintah.)
sumber
*
luar tanda kutip?Ada beberapa masalah dengan kode Anda:
Anda menyimpan output
ls
tanpa mengekstraksi karakter baris baru$list
.ls
menampilkan daftar nama file yang dipisahkan dengan karakter baris baru.newline
adalah karakter yang valid seperti halnya dalam nama file, sehingga output tidak dapat digunakan dengan andal. Misalnyals
output untuk direktori yang berisia
danb
sama dengan yang untuk direktori yang berisi satu file yang disebuta<newline>b
.Anda tidak memeriksa kegagalan perintah itu. Secara umum Anda harus memeriksa status keluar dari perintah, tetapi itu terutama benar
cd
, karena sisa perintah menganggap Anda berada di direktori baru itu, dan itu bisa memiliki konsekuensi dramatis ketika Anda tidak.Shell POSIX telah mempertahankan path (satu) ke direktori saat ini dalam
$PWD
variabel, jadi Anda tidak perlu menggunakan di
sini (terutama dalam kasus umum karena substitusi perintah akan menghapus karakter baris baru dari path). Juga,pwd
mv
terima jalur relatif sehingga Anda tidak perlu membangun jalur absolut.Meninggalkan variabel yang tidak dikutip adalah operator split + glob di shell. Yaitu, isi dari variabel dipisah (pada separator yang disebutkan
$IFS
dengan aturan khusus untuk spasi putih), dan setiap elemen yang dihasilkan dari pemisahan tersebut dicari untuk karakter wildcard sehingga mereka dapat diperluas ke daftar file yang cocok.Di sini, Anda ingin pemisahan, tetapi hanya pada karakter baris baru, dan Anda tidak ingin globbing, jadi Anda harus menonaktifkannya:
Sekali lagi, membiarkan variabel tidak dikutip adalah operator split + glob . Di sini, Anda tidak ingin keduanya, jadi Anda perlu mengutip variabel-variabel tersebut.
Seperti yang telah disebutkan, wildcard hanya diperluas ketika tidak dikutip, untuk itu Anda perlu
*
mengeluarkannya dari kutipan. Jika Anda telah menonaktifkan globbing sebelumnyaset -f
, Anda harus mengaktifkannya kembaliset +f
sebelum memanggil perintah itu.Cara yang lebih baik untuk menulisnya adalah:
Beberapa catatan:
data
folder.-i
opsimv
).*/
, kami hanya beralih ke direktori , tetapi itu juga termasuk tautan simbolik ke direktori. Jika Anda tidak mau, Anda harus menambahkan[ -L "${folder%/}" ] && continue
di dalam loop.*/
akan meluas ke dirinya sendiri, jadi Anda akan menerima pesan kesalahan danmv
mengatakan tidak dapat menemukan file yang dipanggil*/data/*
. Demikian pula, jika tidak ada file tidak disembunyikan di salah satu folder, Anda akan mendapatkan pesan kesalahan yangthat-folder/data/*
tidak ada.sumber