opensourcejason.info
bash for loop

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:

for FILE in `ls -1`
do
   echo $FILE
   #Do other stuff with file
done

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:

#Set the input field separator to a newline or linebreak.
#echo -en means interpret escape characters, and dont insert an additional newline
IFS=`echo -en "\n\b"`
for FILE in `ls -1`
do
   echo $FILE
   #Do other stuff with file
done

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:

for FILE in *
do
    #do stuff with file
done

abc — 17 December 2007, 18:20

last white box should say "for FILE in *" not "for $FILE in *".. Yes?

Jason — 11 March 2008, 23:49

Yes, you're right. I've updated it.

jujubee — 15 April 2008, 02:45

Also

find . -type f -iname '*whatever*' | while read file; do

   # do stuff with $file

done

jujubee — 15 April 2008, 02:46

Or just use your ls command if you're comfortable with it

ls -1 | while read file; do ...; done

jujubee — 08 April 2009, 20:34

what is this strange programming language ur using


Comments

Add Comment 
Sign as Author 
Enter code 217