[BASH] Getting a filename its extension

Heyas

As i often have decide things upon a filename its extension, i thought i'd write a script:
Just wondering if there would be a more efficent way?

out=""
FN=$( echo "$1" | sed s," ","",g)	# Remove any spaces and make it a single string
for chance in $(echo "$FN"|sed s,"\."," ",g)	# Use dots as string seperators
do	out="$chance"
done
if [ "$out" = "$FN" ]
then	echo ""
else 	echo "${out%\ /}" 	# Remove any tailing or single space
fi

Thank you

ext=${1##*.}
if [ "$ext" = "$1" ]; then
  echo ""
else
  echo "$ext"
fi
1 Like

Oh my...
In almost every script i have: XY=${0##*/} to get the basename... :rolleyes:

Sometimes the solution is in front of your eyes, one just doesnt see (reckognize) it (as such).

Another approach:

IFS=. read first last <<< "$1"
echo "${last##*.}"
1 Like

The IFS doesnt handle filenames with multiple dots (the way you used it).
But the same, thats NOT regex - is it?, substitution as neutro does, making the previous read command pointless, or not?

EDIT2:
I thought similar, but failed at the 2nd step, which was 'Neutro's solution.

Hi Sea, the previous read command is not useless, it is there to cater for the possibilty that a filename has no extension. It splits the filename into a first part before the first dot and (into variable first ) and a last part (into variable last ) that contains everything after the first dot.

If the file contains no extension, then the variable last will be empty and thus echo "${last##*.}" will produce an empty string ( "" ).
If there is an extension then echo "${last##*.}" will produce the part after the last dot..

It is indeed not REGEX; it is parameter expansion...

1 Like

Using a bash array:

FN=ABC.CDE.DEF
IFS=. read -a PARTS <<< "$FN"
echo ${#PARTS[@]} ${PARTS[-1]}
3 DEF

Traditional Bourne shell needs an external tool:

expr x"$1" : x'.*\.\(.*\)'

(t)csh have a nice built-in:

echo "$1:e"