Handling whitespace in bash for loops

Tonight I was trying to cleanup my macports installation by uninstalling the packages that are no longer active. I decided to write a script to do this, instead of manually uninstalling them one by one. But in writing the script I came across something I had never seen and the google didn’t give me a clear answer so I thought I would share.

A typical for loop might look like:

  1. $ for file in `ls`
  2. > do
  3. >     echo $file
  4. > done

And this assumes there are no spaces in any of the files returned by ls. I did not know this. So I started doing something similar with this:

  1. $ for package in `port installed | awk 'NF==2{print $0}' `
  2. > do
  3. >     echo $package
  4. > done

But I got output that looked like this:

  1. curl
  2. @7.17.1_0
  3. gettext
  4. @0.17_2

And wanted output like this:

  1. curl @7.17.1_0
  2. gettext @0.17_2

The problem is the awk output had spaces in it which were split by the for loop processing. And well to handle the spaces as desired you need to pipe the output to a while loop like so:

  1. $ port installed | awk 'NF==2{print $0}' | while read pakage
  2. > do
  3. >     sudo port uninstall $package
  4. > done

And now $package is what I expect including the spaces, and my macports installation is a little cleaner.

blog comments powered by Disqus