[Linux] 使用 shell 截取檔案的檔名與副檔名
今天工作時,遇到一個小問題,
用 find 指令找到的檔案,想要把副檔名的部分拿掉,給另一個程式作為參數:
root@home ~/Software/OS $ find ./ -type f .//android-x86-4.4-RC2.iso .//CentOS-5.4-x86_64-bin-DVD.iso .//CentOS-5.4-x86_64-sha1sum.txt .//CentOS-6.2-x86_64-bin-DVD1.iso .//CentOS-6.2-x86_64-bin-DVD2.iso .//CentOS-6.2-x86_64-sha1sum.txt .//CentOS-6.4-x86_64-bin-DVD1.iso .//CentOS-6.4-x86_64-bin-DVD2.iso .//MacOS10.7.dmg .//MacOS10.8.dmg .//ParallelsDesktop-9.0.24172.951362.dmg .//ubuntu-13.10-desktop-amd64.iso .//VirtualBox-4.3.14-95030-OSX.dmg
上面是 find 指令的結果,我想做的是把檔名部分和副檔名部分截取出來,
想要作出下列的效果:
root@home~/Software/OS $ for f in `find ./ -type f`; do echo extracted $f to name and ext; done extracted .//android-x86-4.4-RC2.iso to name and ext extracted .//CentOS-5.4-x86_64-bin-DVD.iso to name and ext extracted .//CentOS-5.4-x86_64-sha1sum.txt to name and ext extracted .//CentOS-6.2-x86_64-bin-DVD1.iso to name and ext extracted .//CentOS-6.2-x86_64-bin-DVD2.iso to name and ext extracted .//CentOS-6.2-x86_64-sha1sum.txt to name and ext extracted .//CentOS-6.4-x86_64-bin-DVD1.iso to name and ext extracted .//CentOS-6.4-x86_64-bin-DVD2.iso to name and ext extracted .//MacOS10.7.dmg to name and ext extracted .//MacOS10.8.dmg to name and ext extracted .//ParallelsDesktop-9.0.24172.951362.dmg to name and ext extracted .//ubuntu-13.10-desktop-amd64.iso to name and ext extracted .//VirtualBox-4.3.14-95030-OSX.dmg to name and ext
但是,要如何用 shell 從變數中截取出檔名和副檔名呢?
stackoverflow: Extract filename and extension in bash 這邊有人提出了非常好又簡潔的方法,
取副檔名:extension=”${filename##*.}”
取檔名:filename=”${filename%.*}”
嗯… 第一次看也是看不懂…
查了一下,這是 shell 的 parameter substitution~
(可參考 http://www.tldp.org/LDP/abs/html/parameter-substitution.html#PSOREX2)
## 是從變數內容的前面,移除與 ## 後面定義的 pattern (也就是 *.) 相符合的部分(越長越好),
因此檔名的部分加上 . 就會被移除,留下最後面的副檔名~
% 是從變數內容的後面,移除與 % 後面定義的 pattern (也就是 .*) 相符合的部分(越短越好),
因此 .副檔名 就會被移除掉,留下前面的檔名部分~
下面是執行的結果:
root@home~/Software/OS $ for f in `find ./ -type f`; do echo extracted $f to ${f%.*} and ${f##*.}; done extracted .//android-x86-4.4-RC2.iso to .//android-x86-4.4-RC2 and iso extracted .//CentOS-5.4-x86_64-bin-DVD.iso to .//CentOS-5.4-x86_64-bin-DVD and iso extracted .//CentOS-5.4-x86_64-sha1sum.txt to .//CentOS-5.4-x86_64-sha1sum and txt extracted .//CentOS-6.2-x86_64-bin-DVD1.iso to .//CentOS-6.2-x86_64-bin-DVD1 and iso extracted .//CentOS-6.2-x86_64-bin-DVD2.iso to .//CentOS-6.2-x86_64-bin-DVD2 and iso extracted .//CentOS-6.2-x86_64-sha1sum.txt to .//CentOS-6.2-x86_64-sha1sum and txt extracted .//CentOS-6.4-x86_64-bin-DVD1.iso to .//CentOS-6.4-x86_64-bin-DVD1 and iso extracted .//CentOS-6.4-x86_64-bin-DVD2.iso to .//CentOS-6.4-x86_64-bin-DVD2 and iso extracted .//MacOS10.7.dmg to .//MacOS10.7 and dmg extracted .//MacOS10.8.dmg to .//MacOS10.8 and dmg extracted .//ParallelsDesktop-9.0.24172.951362.dmg to .//ParallelsDesktop-9.0.24172.951362 and dmg extracted .//ubuntu-13.10-desktop-amd64.iso to .//ubuntu-13.10-desktop-amd64 and iso extracted .//VirtualBox-4.3.14-95030-OSX.dmg to .//VirtualBox-4.3.14-95030-OSX and dmg
這個方法對於檔名中有多個 . 的也是可以處理,
像是 abc.first.second 可以正確的取出檔名部分是 abc.first,而副檔名是 second 喔,
真是太強大了~~ ^^
root@home~/Software/OS $ echo $a abc.first.second root@home~/Software/OS $ echo ${a%.*} abc.first root@home~/Software/OS $ echo ${a##*.} second
//
//
(本頁面已被瀏覽過 6,570 次)