Shell
刪除多個可能的後綴
範例:我想創建一個快速命令來縮小圖像(對於我的文件瀏覽器)。
... FN="/tmp/some-image.jpg" gm convert "$FN" -resize 50% "$(dirname $FN)/$(basename $FN .jpg/png/gif).jpg" ...
如何指定應該去除多個後綴?
basename
只需要刪除一個後綴,並給出您不想要的基本名稱(刪除目錄組件),因此basename
它並不是真正適合您需要的工具。從字元串中提取數據的傳統工具是
expr
:FN_without_extension=$(expr "x$FN" : 'x\(.*\)\.')
但是現代 shell(如
zsh
,bash
,ksh
,ash
,yash
, 所有 POSIX 兼容sh
…)都有內置的運算符,所以現在你幾乎不需要expr
(最好避免,因為它有一些問題)。${var%pattern}
從末尾刪除(最小)部分匹配模式
$var
gm convert "$FN" -resize 50% "${FN%.*}.jpg"
Shell 喜歡
tcsh
或zsh
有運算符來刪除擴展。Zsh:gm convert $FN -resize 50% $FN:r.jpg
(
r
對於rootname)。如果要刪除副檔名,只有當它是 jpg/png/gif 之一時,它才會變得更加複雜並且依賴於 shell。
與
zsh
:gm convert $FN -resize 50% ${FN%.(jpg|png|gif)}.jpg
與
ksh
:gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"
與
bash
:shopt -s extglob gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"
與
expr
:gm convert "$FN" -resize 50% "$( expr \( "x$FN" : '\(.*\)\.png$' \| \ "x$FN" : '\(.*\)\.jpg$' \| \ "x$FN" : '\(.*\)\.gif$' \| "x$FN" \) : 'x\(.*\)')".jpg
(是的,這很複雜,這是為了解決一些問題
expr
)。通過一些
expr
實現,它可以簡化為:expr \( "x$FN" : '\(.*\)\.\(png\|jpg\|gif\)$' \| "x$FN" \) : 'x\(.*\)'
你也可以使用
sed
:FN_without_ext=$(printf '%s\n' "$FN" | sed -e '$!b' -e 's/\.png$//;t' -e 's/\.gif$//;t' -e 's/\.jpg$//')
如果您希望它不區分大小寫,您可以將上述
png/gif/jpg
所有解決方案中的 替換為[pP][nN][gG]...
,一些外殼/工具也可以進行不區分大小寫的匹配:
zsh
:setopt extendedglob FN_without_ext=${FN%.(#i)(gif|png|jpg)}
ksh93
:FN_without_ext=${FN%.~(i:gif|png|jpg)}
bash
:shopt -s nocasematch LC_ALL=C if [[ $FN =~ (.*)\.(gif|png|jpg)$ ]]; then FN_without_ext=${BASH_REMATCH[1]} else FN_without_ext=$FN fi
GNU
sed
:FN_without_ext=$(printf '%s\n' "$FN" | sed -r '$s/\.(png|gif|jpg)$//I')