The real question is, why do any operating systems place significance in '.' ? There's no technical reason to do so, it's just a standard which can help you assume the file type without checking.
If you rename an MP3 file to .txt and try to open it in windows you will immediately see why that idea has drawbacks: you suddenly "can't" open the file correctly. Technically speaking, without any speed considerations and so forth the "best" way would probably be to determine the file type before deciding what to do with it, as extensions are easily fumbled and can cause issues.
The reason linux doesn't care about a period in the name is the same reason a non-computer person doesn't: there's no inherent difference between a period and any other character other than the fact that some programs happen to be coded to see that period and treat it specially.
Assuming you actually just want the extension (which is not what both of your snippets do), you could use this:
ext(){
extension=
[[ $1 =~ \. ]] && extension="${1##*.}"
echo "$1 -> ${extension:-No extension}"
}
ext something. # something. -> No extension
ext something.txt # something.txt -> txt
ext something # something -> No extension
ext som.thing.mp3 # som.thing.mp3 -> mp3
ext .whatever # .whatever -> whatever
*Note that last one.
If you actually want to return the file name itself when there is no extension, like your code does, there's no reason to use the long, SH style second snippet you have. You've written:
ext() {
extension=${1##*.}
if [ -z "$extension" ]; then
echo "$1"
else
echo "$extension"
fi
}
Which is actually just:
ext(){
extension="${1##*.}"
# This line is what your first snippet is doing:
# echo "$extension"
# This line is what your second snippet is doing:
[[ $extension ]] && echo "$extension" || echo "$1"
}
Which is actually just:
# First snippet
ext(){
echo "${1##*.}"
}
# Second snippet
ext(){
extension="${1##*.}"
echo "${extension:-$1}"
}
You can't take for granted anything that users can input basically.If you want to see what kind of file it actually is, try the file command. Because parsing file names to try to figure out the file type is not the only way to skin that cat. You can even have a filename in linux called simply: \
example.tar.gz
you will strip all suffixes starting from the first dot, which will not get the single extension necessary to call the right program for processing. And if your file name has no (dot-separated) "extension(s)" your function will print the whole entered name, so you'd need an extra test to return an empty string in that case..
.