範例:我想建立一個快速命令來縮小圖像(對於我的文件瀏覽器)。
...
FN="/tmp/some-image.jpg"
gm convert "$FN" -resize 50% "$(dirname $FN)/$(basename $FN .jpg/png/gif).jpg"
...
如何指定應刪除多個後綴?
答案1
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
有運算子來刪除擴充。茲什:
gm convert $FN -resize 50% $FN:r.jpg
(r
為了根名)。
如果您想刪除擴展名,僅當它是 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]...
,一些 shell/工具也可以進行不區分大小寫的匹配:
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')
答案2
這應該能解決問題嗎?它基本上是刪除.mp3
或.wav
擴展:
$ basename -s .wav $(basename -s .mp3 'some_file.mp3')
some_file
$ basename -s .wav $(basename -s .mp3 'some_file.wav')
some_file
$ basename -s .wav $(basename -s .mp3 'some_file.rs')
some_file.rs