protecting whitespace from the Bourne "for" command

L. Mark Larsen lml at cbnews.att.com
Sat Dec 8 13:26:52 AEST 1990


In article <16570 at cgl.ucsf.EDU>, rodgers at maxwell.mmwb.ucsf.edu (ROOT) writes:
# Does anyone know how to protect whitespace in items to be passed to the
# "for" operator of the Bourne shell?  Consider the script:
# 
# #! /bin/sh
# #
# # Define list
# #
# list="'a b' c"
# #
# # Use list
# #
# for item in $list
# do
#    grep $item inputfile
# done
# #
# # Script complete
# 
# where "inputfile" might contain, for example:
# 
# a b
# c
# d
# 
One way to do what you want is to set the positional parameters and loop
through them:

set -- 'a b' c
for item
do
	grep "$item" inputfile
done

Of course, if your script was called with arguments, you may have a small
problem to get around - especially if any of the original arguments had
embedded white space.  Possibly the safest and easiest thing to avoid this
sort of problem might be to use a function:

doit()
{
	for item
	do
		grep "$item" inputfile
	done
}

doit 'a b' c	# once

for arg
do
	# process original args differently
	echo $arg
done

doit 'd e' f	# again

The function idea is quite useful in other situations.  For example, suppose 
you want to change the value of some variable in a script but the change is
taking place inside of a loop where the output is redirected.  With the Bourne
shell (fixed in the Korn shell) such a loop is run in a subshell which means
the change to the variable in the script's environment is lost:

# with /bin/sh, foo is not changed
foo=bar
for i
do
	foo=$i
	echo "loop: foo = $foo"
done >/dev/tty
echo "final = $foo"

However, by putting the loop in a function, the change does take place to
the script's environment:

# in this case, foo *is* changed
doit()
{
	for i
	do
		foo=$i
		echo "loop: foo = $foo"
	done
}

foo=bar
doit $* >/dev/tty
echo "foo = $foo"

cheers,
L. Mark Larsen
lml at atlas.att.com



More information about the Comp.unix.shell mailing list