[Gllug] Bash scripting question

Tethys sta296 at astradyne.co.uk
Fri Aug 11 08:22:20 UTC 2006


ccooke writes:

>IFS=$'\n' tags=( $( vorbiscomment "$1" ) )
>for tag in "${tags[@]}"
>do
>	echo "$tag"
>done
>
>This sets the Input Field Separator to newline (\n) only, just for 
>the array assignment line.

That's the theory anyway. But there seems to be something special
about the way the shell treats IFS. I was playing around with this
last night after seeing Dylan's original message. Unlike a normal
shell variable, the value of IFS persists for more than just the
command in question. You need to explicitly unset it (or save and
restore the previous value). Try it and see:

	leto:% cat foo
	This file
	has 3
	lines
	leto:% set | grep ^IFS
	IFS=$' \t\n'
	leto:% tags=($(cat foo)) && echo ${#tags[@]}
	5
	leto:% IFS=$'\n' tags=($(cat foo)) && echo ${#tags[@]}
	3
	leto:% tags=($(cat foo)) && echo ${#tags[@]}
	3
	leto:% set | grep ^IFS
	IFS=$'\n'
	leto:% unset IFS
	leto:% tags=($(cat foo)) && echo ${#tags[@]}
	5

Strange, huh? It's not just a bashism either. pdksh does exactly
the same.

>for (( tag = 0; tag < ${#tags[@]}; tag++ ))
>do
>	echo "${tags[$tag]}"
>done
>
>... which is a little cleaner and will run with less load on the 
>system.)

Simpler still... once you've used IFS to get the array loaded correctly,
you can just do:

	for tag in ${tags[@]}
	do
		echo "$tag"
	done

Tet
-- 
Gllug mailing list  -  Gllug at gllug.org.uk
http://lists.gllug.org.uk/mailman/listinfo/gllug




More information about the GLLUG mailing list