split with /bin/sh 

Newsgroups: comp.unix.shell
> I have a row of characters separated by a '+'  ...like so:
>
> bob+smith+william ghol+steve
>
> How can I split the columns and assign each of them to variables.
> into this
>
> var1=bob
> var2=smith
> var3="wiliam ghol"
> var4=steve

This will get you part of the way there

#!/bin/sh
x='bob+smith+william ghol+steve'
OLD_IFS=$IFS    # save internal field separator
IFS="+"         # set it to '+'
set -- $x       # make the result positional parameters
IFS=$OLD_IFS    # restore IFS
var1=$1
var2=$2
var3=$3
var4=$4
echo var1=$var1
echo var2=$var2
echo var3=$var3
echo var4=$var4

output:

var1=bob
var2=smith
var3=william ghol
var4=steve

split with /bin/sh 

Use the 'read' command to do this, it splits the input into variables based on the current contents of $IFS. You can change $IFS to '+' for only the duration of the 'read' command putting the assignement at the beginning of the line, then it will do everything for you at once ;

$ cat file
bob+smith+william ghol+steve
$ IFS=+ read var1 var2 var3 var4 <file
$ set |grep '^var.='
var1=bob
var2=smith
var3='william ghol'
var4=steve
$

split with /bin/sh 

Note, be careful where the read is executed:

echo 'a1 b2 c3' | IFS=' ' read var1 var2 var3 var4
$ set |grep '^var.='

— nothing is set, because the read is executed in the sub shell

echo 'a1 b2 c3' > $tf
IFS=' ' read var1 var2 var3 var4 < $tf
$ set |grep '^var.='
var1=a1
var2=b2
var3=c3
var4=

— get it this time!

# reset vars 1st
$ jot -s ' ' 3 | tee $tf
1 2 3
$ IFS=' ' read var1 var2 var3 var4 < $tf
$ set |grep '^var.='
var1=1
var2=2
var3=3
var4=
export var1 var2 var3
echo 'a1 b2 c3' | IFS=' ' read var1 var2 var3 var4
$ set |grep '^var.='
var1=1
var2=2

— no, even export won't help here!

split with /bin/sh 

q="bob+smith+william ghol+steve"
n=0
IFS="+"
for v in $q
do
    n=`expr $n + 1`
    if expr "$v" : '.* .*' > /dev/null
    then
        z="var$n=\"$v\""
    else
        z="var$n=$v"
    fi
    eval "$z"
done

The above script is purely Bourne shell. If you are using a modern shell, there are more efficient ways of doing it.

For example, in bash or ksh, I'd put the values into an array:

q="bob+smith+william ghol+steve"
oldIFS=$IFS
IFS="+"
var=($q) ## var=(${q// /\ }) # to escape spaces (use \\ on command line)
IFS="$oldIFS"
$ echo ${var[2]}
william ghol

Chris F.A. Johnson