[Linux] 使用 shell 截取檔案的檔名與副檔名

[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 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料