Iterating through a directory in Bash, when the filename has spaces
2007-08-19
I've commonly run into a problem in Bash where I'd like to perform some operation on a number of filenames in a directory. I finally found out an easy way to successfully do this, even when there are files that include spaces in the filename.
I always use an idiom that looks like this:
While this is a nice simple idiom to remember, it causes problems if you have a directory containing filesnames that include spaces. This is because by default, Bash separates the input to an iterating for loop using ANY white spaces, not just newlines. I'd gotten around this in the past using other ugly hacks like piping the directory list into the BASH read command. Well, it turns out, there's a much simpler (and more obvious) solution.
Bash has a number of built-in variables. One of these built-in variables, called $IFS (input field separator) tells Bash how it should divide up items in an input stream for an iterator. So, the problem can be solved with one simple line:
Note that you should store the current IFS in a variable, say, OLDIFS, and set it back after the for statement, in case you use commands later down the road in which you need to parse items by whitespace again (for example, when passing multiple arguments to a program).
But in the end, this is all pointless. All you need to do is remember the magical glob. Globbed filenames will always be expanded properly, using filenames as individual words in the list. So, the best way to do this: