Shell-scripts can easily process files/records line-by-line.
A typical construct to do so is:
ps aux |
while read line do;
echo $line
done
But, this kind of a thing isn't very easy to process outputs of
commands like ifconfig. ifconfig has output in blocks instead of
lines. Recently I had to do it and I was really surprised that I had
no idea of how to parse blocks of data in shell-script. After some
time, I figured it out myself. The pipe command pipes the output to a
shell. So what if that shell contains another shell-script instead of
a single command?
Here's how to parse ifconfig command. The script prints out a list of
interfaces and corresponding IP address (NIL if no IP): (Note:
Brackets fork a new shell)
ifconfig -a |
(
#Read the first line
while read line; do
INTERFACE_ADDR=`echo $line | awk '{print $1}'`
# Read second line in the block and store the IP address, if any
read line;
IP=`echo $line | grep "inet addr" | awk '{print $2}' | cut -d':' -f2`
while true; do
# Skip all other lines from the block
read line;
# End of block is a new line. Start parsing new block then
if [ -z "$line" ]; then
break;
fi
done
echo $INTERFACE_ADDR $IP
done
)
There. This is albeit a simple example. You can construct truly
awesome block parsing constructs using the sub-shell (i.e. the
brackets '()' )
Feature 2:
Wonder why a shell-script doesn't have a block commenting feature?
Wonder no more.
Here is a cool trick using here-documents to comment out a block of shell script
: <<'END1'
"The commented block goes here"
END1
Notes:
1) ":" means "true". /dev/null equivalent for a shell script.
2) Make sure that the string "END1" is the same at both the places,
else, this thing is not going to work.
Happy scripting :-)