
Wednesday July 14, 2004
ksh scripting #4 : list elements v7 and v8
Alan offered cool advise on ksh scripting #3 with pl.sh using "IFS" and "set --".
... and I dig!
So I adapted pl.sh into a shell function. My initial concerns that IFS is not taken in local context of a function was valid afterall. IFS is global and most certainly not just another variable. It got confusing when echo $IFS doesn't show anything and I thought it's spaces. set | grep IFS shows differently. It got even more mysterious when the function was invoked again but produce different result. Only after a bunch of almighty debug printf (ok I used echo) that it became clear IFS was causing my confusion. Just to make matter more difficult for myself I tried to be fancy and do set -- $@ directly. That certainly doesn't work. The moment IFS is set, substitution for $@ no longer shows the char that's IFS but instead, space is substituted!
Here's pl7() which adapted the set -- trick that works:
#
# pl7 - print list elements delimited by '|'
#
function pl7 {
l=$@
IFS='|'
set -- $l
for e
do
echo $e
done
unset IFS
}
And to add some flexibility, I can cater to user specified delimiters which would have been otherwise messy to do in pl version 1:
#
# pl8 - print list elements, $1 is delimiter
#
function pl8
{
d=$1
shift
l=$@
IFS=$d
set -- $l
for e
do
echo $e
done
unset IFS
}
Give it a go:
$ pl7 "lp|x|71|8|Line Printer Admin|/usr/spool/lp|"
lp
x
71
8
Line Printer Admin
/usr/spool/lp
xxx
$ pl8 ":" lp:x:71:8:Line Printer Admin:/usr/spool/lp:
lp
x
71
8
Line Printer Admin
/usr/spool/lp
xxx
$
I guess my intention was clear, in that I'm trying to let ksh do all the work whenever I can avoid a process invocation. Otherwise, it's really much easier to just awk it.
$ head -1 /etc/passwd | nawk -F':' '{while (++i<=NF) print $i}'
or a bit more readable
$ head -1 /etc/passwd | nawk -F':' '{for (i=1;i<=NF;i++) print $i}'
PS: Okay why version 7 and 8? it took me that no. of iteration to figure out IFS. ;)
ksh scripting flashback:
#1
#2
#3
(2004-07-14 00:00:04.0)
Permalink
|