Assign a variable the nth character of a string.

I see a millioin ways to do this with echo, but what I wan to do is assign a variable the "nth" character of an incoming parameter to a ksh script.

$1 will be "pia"

I need to assign the first character to stmttype.

#! /bin/ksh
stmttype=${1:0:1}
echo $stmttype
# ./test.sh pia
p
#

I found that this works

bankid=$1
stmttype=$2
jdd=`date '+%j'`

stid=$(expr substr $2 1 1)

echo "ID: $stid"

Depending on your shell, substr may be needed yes. ${string:offset:length} works in BASH and modern KSH, but if you're stuck with an old Solaris SH or the like, that feature's not there.

for old ksh and sh

#! /bin/ksh 
stmttype=`echo $1 | cut -c1` 
echo $stmttype

Try:

echo "${1%%${1#?}}"

==edit==
as pointed out by alister, it is better to put double quotes around the inner expansion (and only one % is required in this case):

echo "${1%"${1#?}"}"
echo "${1%%${1#?}}"

Why would you do that instead of 'cut'?

Far more efficient to run a shell builtin or string operator than an external application -- especially for tiny amounts of data. It's not a meaningless gripe. whenever we have someone asking "please speed up my script", bad habits like echo | cut/awk/sed are almost always the culprit. Put them in a loop and the penalty adds up quickly. In my early programming days I once wrote a linewrapper which processed text at the blazing speed of 5 kilobytes per second...

Unfortunately, on shells without fancy operators for strings, you're limited in what you can do.

With the sample data provided by the OP, that will work. However, if this is used in a more generalized capacity (if not by the OP, then perhaps by someone who has read this thread), it should be noted that an argument containing pattern matching metacharacters (*, ?, [, etc) will yield unintended results. To protect against this, an additional set of quotes is necessary.

Also, since this task requires that either the data be free of metacharacters or that any metacharacters be quoted, the use of %% isn't needed. % will behave identically.

echo "${1%"${1#?}"}"

It's possible that construct may still have issues with strings beginning with a dash.

Perhaps the following would be the simplest, most robust, and most portable approach which retains the efficiency of a sh builtin:

printf '%.1s' "$1"

Regards,
Alister

2 Likes

Wonderful alister! Double quotes within parameter braces make pattern characters literal ( and can be used even within other double quotes around the variable ), thank you for your insightful and insight giving comment!

--
With the printf suggestion, there would be a problem with multi-byte characters.

1 Like

True. The format string spec for the precision flag specifies bytes not characters. Thank you for making that clear.

Regards,
Alister