今天在學(xué)習(xí)shell腳本攻略第二章2.13 批量重命名和移動(dòng)時(shí),由于我的文件命令有的文件名字中出現(xiàn)空格,出現(xiàn)了許多問(wèn)題,因此將解決問(wèn)題的過(guò)程記錄了下來(lái),希望能夠和大家交流學(xué)習(xí),共同進(jìn)步,謝謝!
問(wèn)題代碼
最終成功代碼
步驟一
思路: 由于在shell中運(yùn)行此腳本時(shí),發(fā)現(xiàn)將找到的文件名按照空格分割開(kāi)來(lái),結(jié)果利用for循環(huán)時(shí),每一個(gè)文件名被打散,例如'./Screenshot from 2017-09-22 14-43-51.png' 拆分成了'./Screenshot\ ' 'from' '2017-09-22'等,所以執(zhí)行錯(cuò)誤. 所以在解決該問(wèn)題時(shí)的第一個(gè)思路就是將文件名正確的讀出來(lái).
解決方案: 將
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?`find . -name "*.png" -o -name -maxdepth 1 -type f`
改為
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?`find . -name "*.png" -o -name -maxdepth 1 -type f -print`
原因: find -print 會(huì)將每一個(gè)查詢(xún)出來(lái)的文件通過(guò)換行符分割開(kāi)
結(jié)果: 依然不行,但是在shell中直接輸入該命令,確實(shí)是換行輸出
步驟二
思路: 雖然輸出是換行輸出,但是是for循環(huán)在讀入的時(shí)候是從一個(gè)大字符串中進(jìn)行分割,而分割的標(biāo)識(shí)是IFS,IFS默認(rèn)分隔符是空格\tab\換行,所以會(huì)將換行符和空格同樣對(duì)待,所以需要更改IFS的分割標(biāo)志.
解決方案:添加代碼
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OLDIFS=$IFS
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IFS=$'\n'
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IFS=$OLDIFS
注意: 這里將IFS的分割標(biāo)志換成了 $'\n' 換行符,如果寫(xiě)成'\n'僅僅表示字母n
結(jié)果: 每一次for循環(huán)能夠得到正確的文件名,但是在執(zhí)行mv命令時(shí)依然報(bào)錯(cuò),原因是文件名中有空格,不能找到正確的文件
步驟三
思路: 在shell中直接執(zhí)行mv命令,會(huì)把文件名中帶有空格的文件的文件名的空格進(jìn)行轉(zhuǎn)譯,即將' '轉(zhuǎn)成'\ '.所以這一步的思路就是得到轉(zhuǎn)譯之后的文件名
解決方案:添加代碼
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?img=${img// /\\ }
結(jié)果: 可以將文件名正確的轉(zhuǎn)換成轉(zhuǎn)譯之后的文件名,**但是**依然不能正確運(yùn)行,shell中提示的錯(cuò)誤信息是
mv: cannot stat './Screenshot\ from\ 2017-09-22\ 14-43-51.png': No such file or directory
但是我直接用這個(gè)文件名進(jìn)行mv命令操作是可以進(jìn)行的,所以這個(gè)時(shí)候進(jìn)行最后一步
步驟四
思路: 得到了正確的文件名,但是不能正確的執(zhí)行mv操作,那么問(wèn)題就在腳本的這個(gè)命令上
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?mv "$img" $new
所以我在mv前面加上了一個(gè)預(yù)處理的命令 eval
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?eval mv "$img" $new
mv命令在執(zhí)行前會(huì)先執(zhí)行eval命令,將變量的值轉(zhuǎn)換過(guò)來(lái),然后在執(zhí)行,最后得到了正確的結(jié)果
知識(shí)點(diǎn)
在完成整個(gè)文件批量重命名的過(guò)程中主要用到了一下幾個(gè)知識(shí)
1. find -print 和-print0
2. IFS 分隔符
3. 字符串替換的方法
4. eval命令
5. 以后命名的時(shí)候千萬(wàn)不要在帶空格了,很麻煩
6. 因?yàn)檫@次執(zhí)著于for循環(huán)解決,所以花了點(diǎn)時(shí)間,簡(jiǎn)單的可以使用while read line