Sometimes I need to rename all the files (the renaming convention follows later) in a directory where the filename is always in the form of 'filenamename.extension' (extension always exists and varies). The name may contain whitespaces and characters from the [:graph:] class. My first problem is that it should be absolutely portable between *NIX systems (especially Linux, BSD, later other systems, say AIX). My second problem is with the [:graph:] class. Filenames could be:
cat.txt
dog_and_cat.txt
Where is the cat?.png
my.cat.is.cute.txt.js.html
;;; ;;; ;;;.......321
áéúő _[a lot of whitespaces]_ óü^^^^^ö.jpg
Easy to see, those are difficult to handle and put into a for loop. For example, the
for i in *; do something; done
doesn't always like whitespaces and the weird characters, especially in different operating systems.
The renaming convention is to rename all files to the $FOOBAR.$EXTENSION form where $FOOBAR is some kind of hash, for example md5sum. So in the for loop I have got a line which is like
mv $FILE $(md5sum $FILE | sed 's/\ \ .\+//');
It will move the file to the md5sum of itself, but the extension is disappeared. I want to preserve the extensions, which are almost always in the .[a-zA-Z0-9]{1,3} form. Occasionally there are extensions like .tar.gz which are also needed to be preserved (certainly I could add them into a variable, say MYEXTENSIONS='tar.gz tar.bz2 foo.bar').
My intuition tells me that the problem is solvable with well-parametrized default UNIX/shell commands, but it is extremely difficult for me now. I'm sure I'll learn a lot from the answers. I know I said the magical word portability, but the solution is preferred in bash, if I must specify the language.