Picking a character from a word

Richard A. O'Keefe ok at quintus.UUCP
Sat Apr 23 20:02:18 AEST 1988


In article <578 at amethyst.ma.arizona.edu>,
barsam at eros.ame.arizona.edu (Barsam Marasli)
[ wants to extract the Nth character of an argument in csh() or sh() ].

The most elegant solution would be one which uses the weakest tool,
yet which uses that tool in a "direct" way.  Using 'sed' or 'awk' is
clearly overkill:  all you need is expr(1).

Suppose you have variables
	String		holds the argument
	Pos		says where to start (1..length(String)+1)
	Len		says how much (0..length(String)+1-Pos)
and want
	SubStr
to hold the indicated chunk.  Do
	set SubStr = `expr substr $String $Pos $Len`
in csh(1), or
	SubStr=`expr substr $String $Pos $Len`
in sh(1).  For example, to get the 4th character, you would do
	set SubStr = `expr substr $String 4 1`
{Don't omit the $Len argument!}

Unfortunately, "expr substr" is a BSD-ism which has yet to find its way
into the SVID.  To get something which works in both, you have to use
infix colon.

	set SubStr = `expr $String : '...\(...\)'`		# csh
or
	SubStr=`expr $String : '...\(...\)'`			# sh

where the first set of dots has one dot for each character you DON'T
want, and the second set of dots (between \( and \)) has one dot for
each character you DO want.  This is like an ed(1) pattern, and the
bit between \( and \) is the value returned by expr.  For example,
to get the 4th character, you would do
	SubStr=`expr $String : '...\(.\)'`

Then, of course, there is the slightly less elegant
	SubStr=`echo $String | cut -c4`

There are of course the usual subtleties to worry about if String
contains strange characters.  Strictly speaking, it is best to write
	set SubStr = `expr "$String" : '...\(...\)'`	# csh
	SubStr=`      expr "$String" : '...\(...\)'`	# sh
or even
	Substr=`cut -c4 <<EOF
	$String
	EOF `

Oh the joys of macro processors; fun till it hurts.



More information about the Comp.unix.questions mailing list