Okay, this will be a quickie. Really.
I use for loops in scripts all the time, but for chokes on files with spaces in the name. After years of finding ways to avoid this problem any way I could, I've finally found what I believe to be the solution.
The for command treats any whitespace as a line break. So if you try to use for on a list of files (or folders or whatever) the loop will not function properly on items with spaces in the name. The for command will treat everything after the space as a new item.
Let's say you want to copy every file that starts with "Systems" in the folder "Start" to a folder called "Finish." The "Start" folder contains the items:
Systems Boy
Systems Girl
Systems Baby
James Bond
Bat Man
Using for would go something like this:
for item in `ls Start | grep Systems`
do cp "$item" Finish
done
The for command, however, will treat "Systems" and "Boy" as two separate items, and when the cp command is issued it will complain:
cp: Systems: No such file or directory
cp: Baby: No such file or directory
cp: Systems: No such file or directory
cp: Boy: No such file or directory
cp: Systems: No such file or directory
cp: Girl: No such file or directory
The solution is to forego for and pipe your command to a while read statement like in the following example:
ls Start | grep Systems | while read item
do cp "$item" Finish
done
The quotes around the $item variable are essential. Without them the script will fail in the same way as for. With them, the script works like you wish the for loop did and is able to properly copy files with spaces in the names.
Nice. And by "nice" I mean halle-fuckin-lujah!
I should give some credit for this tip. I originally read about it here at MacGeekery, but didn't quite understand it until I read some posts on various forums. Of course, there's nothing like a real-world problem to solve, and I had this as well to aid my understanding of this method.