Why are you restricting the file name at all? On most file systems, Unix file names can contain any character except for NUL (\0) and forward slash (/). You're better off learning now how to handle unusual file names than to get in the habit of expecting only letters and digits like you've done, and get bitten later when you come across something unexpected.
I suggest doing some reading on how to handle file names with spaces and other odd characters.
The first tip is to always use double quotes around your variables. There are cases when you don't need to, but for a beginner, it's easier to just always do it. This alone will probably deal with the particular problem you're trying to solve right now.
The next thing I would recommend is to read up on and learn to love the find
command, and it particular, its -exec
operator. This makes it easy to do the right thing when operating on a whole directory tree of files. For instance, never do this:
for f in *; do
do-something-with-a-file "$f"
done
This won't work properly if any of the files have spaces, tabs, or newlines in their names (yes file names can contain newlines!). Not only that, but it doesn't let you distinguish between files and directories.
Instead, do this:
find -maxdepth 1 -type f -exec do-something-with-a-file {} \;
The -maxdepth
operator limits the results to just those in the current directory, -type f
tells find
that we only want files, not directories, and -exec somecommand {} \;
executes somecommand
once for each file, passing the file's name (properly quoted) in place of {}
. The backslash before the semicolon is for the sake of the shell, so that the shell won't process the semicolon, and will instead pass it on to the find
command.
This is just a quick start on properly handling file names. Please read a bit on the topic, and post more questions here if you get stuck.
*+
at the end of the regex is wrong. you can use*
(zero-or-more) or+
(one-or-more) here, but using both together the second modifier has no meaning. Also if you intend to check whether$filename
contains ONLY those characters, you need to have^
(beginning-of-line anchor) at the start of the regex. As it is your regex only checks if $filename contains one-or-more letters-or-digits somewhere in it. – cas Mar 31 '16 at 21:06