linux 截取后缀名,Shell 截取文件名和后缀
截取文件名和后綴
編寫Shell腳本的過程中,經常會和文件名和文件路徑打交道。如果用戶輸入了一個文件的全名(可能包含絕對路徑和文件后綴),如何得到文件的路徑名,文件名,文件后綴這些信息呢。Shell腳本擁有強大的字符串處理能力,如果把文件名當做字符串,我們不難使用cut或sed這樣的工具得到我們想要的結果。
$fullfile=/the/path/foo.txt
$fullname=$(basename $fullfile)
$dir=$(dirname $fullfile)
$filename=$(echo $fullname | cut -d . -f1)
$extension=$(echo $fullname | cut -d . -f2)
$ echo $dir , $fullname , $filename , $extension
/the/path , foo.txt , foo , txt
這里使用basename命令可以直接得到包含后綴的文件名,而dirname命令可以得到路徑名,然后就能簡單的用cut截取文件名和后綴名。
更復雜的情況
如果對付簡單應用場景,到這里已經可以打完收工了,但是有時候文件可能不止有一個后綴,比如*.tar.gz,怎樣得到最后一個后綴呢?再cut一回?當然可以,但是如果文件名是mylib.1.0.1a.zip這樣的呢?呃......正則表達式肯定可以。
$ fullname=mylib.1.0.1a.zip
$ filename=$(echo $fullname | sed 's/\.[^.]*$//')
$ extension=$(echo $fullname | sed 's/^.*\.//')
$ echo $filename, $extension
mylib.1.0.1a, zip
這里面的邏輯是這樣的:
文件名:把以.字符開頭以后一直到行尾都是非.字符的子串替換為空。
后綴名:把從行首開始以.字符結尾的子串替換為空。
光用語言把這兩個正則表達式描述出來腦細胞也要死不少。有沒有像上面cut版本一樣簡單容易理解的方法呢?由于.分隔符的個數不確定,正常使用cut來分割最后一個.字符是不太可能的。但是我們可使用 rev 命令將字符串反轉一下,區分后綴和文件名的.字符位置就確定了。截取了想要的部分之后,再次反轉就得到了我們想要的內容。
$ fullname=mylib.1.0.1a.zip
$ filename=$(rev <<< $fullname | cut -d . -f2- | rev)
$ extension=$(rev <<< $fullname | cut -d . -f1 | rev)
$ echo $filename, $extension
mylib.1.0.1a, zip
使用參數擴展
其實不借助復雜的正則表達式,甚至不調用basename, dirname, cut, sed命令,shell腳本一樣可以做到所有的操作。看下面的實現:
$ fullfile=/the/path/mylib.1.0.1a.zip
$ fullname="${fullfile##*/}"
$ dir="${fullfile%/*}"
$ extension="${fullname##*.}"
$ filename="${fullname%.*}"
$ echo $dir , $fullname , $filename , $extension
/the/path , mylib.1.0.1a.zip , mylib.1.0.1a , zip
真是不能再簡潔了,大括號之內變量名配合幾個神奇的字符,就是Shell的參數擴展(Parameter Extension)功能。
${fullfile##*/}:從前面開始刪除fullfile中最大匹配(longest matching pattern) */ 的字符串
${fullfile%/*}:從后面開始刪除fullfile中最小匹配(shortest matching pattern) /* 的字符串
${fullname##*.}:從前面開始刪除fullname中最大匹配(longest matching pattern) *. 的字符串
${fullname%.*}:從后面開始刪除fullname中最小匹配(shortest matching pattern) .* 的字符串
參數擴展有多種形式,在shell編程中可以用作參數的拼接,字符串的替換,參數列表截取,變量初值等操作,這里不再詳述,請參考后面的功能列表和官方文檔
參數擴展功能列表
參數形式
擴展后
x{y,z}
xy xz
${x}{y, z}
${x}y ${x}z
${x}{y, $z}
${x}y ${x}${z}
${param#pattern}
從param前面刪除pattern的最小匹配
${param##pattern}
從param前面刪除pattern的最大匹配
${param%pattern}
從param后面刪除pattern的最小匹配
${param%%pattern}
從param后面刪除pattern的最大匹配
${param/pattern/string}
從param中用string替換pattern的第一次匹配,string可為空
${param//pattern/string}
從param中用string替換pattern的所有匹配,string可為空
${param:3:2}
截取$param中索引3開始的2個字符
${param:3}
截取$param中索引3至末尾的字符
${@:3:2}
截取參數列表$@中第3個開始的2個參數
${param:-word}
若$param為空或未設置,則參數式返回word,$param不變
${param:+word}
若$param為非空,則參數式返回word,$param不變
${param:=word}
若$param為空或為設置,則參數式返回word,同時$param設置為word
${param:?message}
若$param為空或為設置,則輸出錯誤信息message,若包含空白符,則需引號
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的linux 截取后缀名,Shell 截取文件名和后缀的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux识别fat16还是32,FAT
- 下一篇: linux io读写次数 oid,Oid