Pitfalls of shell scripting. Part 3
Looping constructs.
FOR
for var in list
do
commands
done
- list can be a space separated set of values on which we want to operate.
- One limitation here is any word that has a space in it has to be enclosed in double quotes("") for the shell to treat them as a single element in the list.
- The power of this loop is that the list does not have to be hard coded. It can be the output of a command.
for word in I don\'t know if "this'll" work
do
echo "WORD = $word"
done
OR
list="word1 word2 word3 word4"
list=$list" word5"
for word in $list
do
echo "WORD = $word"
done
Observe the second line of the listing. This is how concatenation happens in shell scripting.
OR
for word in `cat words`
do
echo "WORD = $word"
done
- A problem here or with any of the above methods is that if the file or the listing has spaces, newlines, etc. every space separated value will be considered an individual element and processed separately, while this is not we wanted.
- The reason here is something more internal to UNIX. In Unix, there is something called the "Internal Field Separator(IFS)" which determines what identifier acts as the delimiter.
- By default IFS is set to white space, tab and a newline. So when it encounters any one of them the next stuff becomes a separate element.
- If in our case we want each newline alone to be considered an element, we will have to set the IFS to "\n" explicitly before processing the for loop.
IFS=$'\n'
for word in `cat words`
...
Anything more than one character has to follow this syntax,
IFS=$[characters]
otherwise, one can write simply
IFS=:
if we only want the ":" to be the field separator.
Read this post to find out some effective programs with this technique.
There is also a C-style for loop, kept in order to allow C-programmers to be at ease. :-)
for (( variable assignment; condition; iteration process ))
eg.,
for (( a = 1, b=8; a
This has multiple advantages over the normal for loop.
1. Spaces are allowed between variable assignment. (unlike the traditional style like THIS)
2. Multiple variables can be initialized.
3. Accessing variables doesn't require a dollar($) sign.
WHILE
This is also a similar construct like the FOR loop.
while test command
do
commands
done
The key to the while loop is that the command being tested on the first line has to change over the course of the loop, else it will be an infinite loop.
eg.,
while [ $var1 -gt 10 ]
do
echo "Something"
var1=$[ $var1 + 2 ]
done
Like IF, only the exit status of the last command on the first line is used to evaluate the loop's running.
Controlling the loop
- Extending the traditional programming styles, bash also provides the two commands "break" and "continue", which serve pretty much the same function as their counterparts in other famous languages.
- One additional feature of both this commands is they can be told to break "n" levels in cases of multiple nesting ( where the current level of nesting is n = 1 ). Consider this example.
for (( a = 1; a < 4; a++ ))
do
echo "Outer: $a"
for (( b = 1; b < 5; b++ ))
do
echo "Inner: $b"
if [ $b -gt 3 ]
then
break 2 # tells to break 2 levels.
fi
done
done
This will give:
Outer: 1
Inner: 1
Inner: 2
Inner: 3
Inner: 4
Since it breaks the outer loop the whole execution stops. Similarly "continue" can also be used.
Processing output of loops
There is one small piece of beauty in the looping constructs. Instead of echo-ing things from within the loop, one can decide to write them to a file or pipe to a command.
eg.,
for file in /home/user/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
else
echo "$file is a file"
fi
done > fileList.txt
Instead of printing the output, it will write all of it to the file mentioned at the end of the loop.
No comments:
Post a Comment