示例:我想创建一个快速命令来缩小图像(对于我的文件浏览器)。
...
FN="/tmp/some-image.jpg"
gm convert "$FN" -resize 50% "$(dirname $FN)/$(basename $FN .jpg/png/gif).jpg"
...
Run Code Online (Sandbox Code Playgroud)
如何指定应删除多个后缀?
Sté*_*las 15
basename
只需要删除一个后缀,并给出您不想要的基本名称(删除目录组件),因此basename
它并不是真正适合您需要的工具。
从字符串中提取数据的传统工具是expr
:
FN_without_extension=$(expr "x$FN" : 'x\(.*\)\.')
Run Code Online (Sandbox Code Playgroud)
但是现代 shell(如zsh
, bash
, ksh
, ash
, yash
, 所有 POSIX 兼容sh
......)都有内置的运算符,所以expr
现在你几乎不需要(最好避免,因为它有一些问题)。
${var%pattern}
Run Code Online (Sandbox Code Playgroud)
从末尾删除(最小)部分匹配模式 $var
gm convert "$FN" -resize 50% "${FN%.*}.jpg"
Run Code Online (Sandbox Code Playgroud)
Shell 喜欢tcsh
或zsh
有操作员来删除扩展。Zsh:
gm convert $FN -resize 50% $FN:r.jpg
Run Code Online (Sandbox Code Playgroud)
(r
用于根名称)。
如果您想删除扩展名,只有当它是 jpg/png/gif 之一时,这会变得更加复杂并且依赖于 shell。
与zsh
:
gm convert $FN -resize 50% ${FN%.(jpg|png|gif)}.jpg
Run Code Online (Sandbox Code Playgroud)
与ksh
:
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"
Run Code Online (Sandbox Code Playgroud)
与bash
:
shopt -s extglob
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"
Run Code Online (Sandbox Code Playgroud)
与expr
:
gm convert "$FN" -resize 50% "$(
expr \( "x$FN" : '\(.*\)\.png$' \| \
"x$FN" : '\(.*\)\.jpg$' \| \
"x$FN" : '\(.*\)\.gif$' \| "x$FN" \) : 'x\(.*\)')".jpg
Run Code Online (Sandbox Code Playgroud)
(是的,这很复杂,这是为了解决 的一些问题expr
)。
通过一些expr
实现,它可以简化为:
expr \( "x$FN" : '\(.*\)\.\(png\|jpg\|gif\)$' \| "x$FN" \) : 'x\(.*\)'
Run Code Online (Sandbox Code Playgroud)
您还可以使用sed
:
FN_without_ext=$(printf '%s\n' "$FN" |
sed -e '$!b' -e 's/\.png$//;t' -e 's/\.gif$//;t' -e 's/\.jpg$//')
Run Code Online (Sandbox Code Playgroud)
如果您希望它不区分大小写,您可以将png/gif/jpg
上面所有解决方案中的替换为[pP][nN][gG]...
,某些外壳/工具也可以进行不区分大小写的匹配:
zsh
:
setopt extendedglob
FN_without_ext=${FN%.(#i)(gif|png|jpg)}
Run Code Online (Sandbox Code Playgroud)
ksh93
:
FN_without_ext=${FN%.~(i:gif|png|jpg)}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
GNU sed
:
FN_without_ext=$(printf '%s\n' "$FN" | sed -r '$s/\.(png|gif|jpg)$//I')
Run Code Online (Sandbox Code Playgroud)