Remove multiple possible suffixes

basename only takes one suffix to remove, and gives the base name (removes the directory components) which you don't want there anyway, so basename is not really the right tool for your need.

The traditional tool to extract data from a string is expr:

FN_without_extension=$(expr "x$FN" : 'x\(.*\)\.')

But modern shells (like zsh, bash, ksh, ash, yash, all POSIX compliant sh...) have builtin operators for that, so you hardly ever need expr nowadays (and it's best avoided as it's got a few issues).

${var%pattern}

removes the (smallest) part matching pattern from the end of $var

gm convert "$FN" -resize 50% "${FN%.*}.jpg"

Shells like tcsh or zsh have operators to remove extensions. Zsh:

gm convert $FN -resize 50% $FN:r.jpg

(r for rootname).

If you want to remove the extension, only if it's one of jpg/png/gif, then that becomes more complicated and shell dependant.

With zsh:

gm convert $FN -resize 50% ${FN%.(jpg|png|gif)}.jpg

With ksh:

gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"

With bash:

shopt -s extglob
gm convert "$FN" -resize 50% "${FN%.@(jpg|png|gif)}.jpg"

With expr:

gm convert "$FN" -resize 50% "$(
  expr \( "x$FN" : '\(.*\)\.png$' \| \
          "x$FN" : '\(.*\)\.jpg$' \| \
          "x$FN" : '\(.*\)\.gif$' \| "x$FN" \) : 'x\(.*\)')".jpg

(yes, that's convoluted, and that's to work around some of the issues of expr).

With some expr implementations, it can be simplified to:

expr \( "x$FN" : '\(.*\)\.\(png\|jpg\|gif\)$' \| "x$FN" \) : 'x\(.*\)'

You could also use sed:

FN_without_ext=$(printf '%s\n' "$FN" |
  sed -e '$!b' -e 's/\.png$//;t' -e 's/\.gif$//;t' -e 's/\.jpg$//')

If you want it case insensitive, you can replace the png/gif/jpg in all those solutions above with [pP][nN][gG]..., some shells/tools can also do case insensitive matching:

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')

Tags:

Shell

Basename