Hi brettmjohnson,
what will the entire script do maybe i can bring you a better solution.
/Rob
Main Topics
Browse All TopicsI am having difficulty splitting a colon-delimited string and assigning the
tokens to an array in a bash shell script. I want to assign the passwd fields
returned by `id -P username` to an array.
Given that
`id -P cyrus`
returns
cyrus:*:77:6::0:0:Cyrus User:/var/imap:/usr/bin/fa
I wish to assign the fields to an array, say pw, such that
pw[0] = cyrus
pw[1] = *
pw[2] = 77
...
pw[8] = Cyrus User
pw[9] = /var/imap
... etc
I already discovered that ' set -f ' avoids the '*' from getting filename-expanded.
I tried using awk to split the colon-delimited string, but the GECOS field can contain spaces,
resulting in its value getting further split during the array assignment:
...
pw[8] = Cyrus
pw[9] = User
....
I have a feeling that there is a simple solution, but I haven't found it yet.
Equally acceptable would be a 'read'- style assignment to multiple variables.
Something like
IFS=':'
read f_uname f_pass f_uid f_gid ...
But read takes intput from stdin.
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
> ... awk 'BEGIN{FS=":";OFS=","; ...
Unfortunately, the GECOS field can contain commas (it is actually a comma-separated list in itself).
I have already used awk for splitting, but I was looking for a slightly more elegant solution.
> what will the entire script do maybe i can bring you a better solution.
I am writing a set of adminstration scripts for a client that has a Linux box
acting as a web server for 2 dozen virtual domains and a mail server (using Qmail)
for both local users (shell acct, POP3/SMTP) and "virtual users" (forwarding all
mail for a virtual domain to an external party).
I am using the username, UID, full name extracted from the GECOS field, and
home directory field for various administrative tasks.
> Just curious, what version of "id" are you using ?
Excellent observation. Although the target machine is running RH 7.1,
I was prototyping the utility on Mac OS X, which uses id v1.19 from FreeBSD.
I will probably have to change it to grep the /etc/passwd file for the appropriate fields.
I like the idea of using 'cut' to split the string, 'tho.
But I will going to give an A grade to a good solution that uses a built-in
or external command that doesn't need to iterate (reparsing the string each time).
I found this page:
http://www.unixguide.net/u
It appears that you can do something like this:
IFS=:
read f_uname f_pass f_uid f_gid f_therest <<END
$(id -P cyrus)
END
echo $f_uname
echo $f_pass
echo $f_uid
echo $f_gid
echo $f_therest
You should also be able to do something like this:
read f_uname f_pass f_uid f_gid f_therest < <(IFS=:; id -P cyrus)
I tested both approaches using "echo $PATH" as the command -- instead of "id -P cyrus" -- using bash on Mandrake 10 and they worked as advertised.
brettmjohnson,
Made a function for this purpose with the same syntax as explode in php
# Function
myexplode () {
array=`echo $2 | awk "BEGIN{FS=\"$1\";OFS=\"NIS
echo $array
i=0
for ar in $array
do
tmp[$i]=`echo "$ar" | sed 's/KALLEKOSKIT/ /g'`
i=`expr $i + 1`
done
return $tmp
}
# End func
#test script
tmp= myexplode ":" "`tail -n 1 /etc/passwd`"
echo ${tmp[4]}
exit
# End
/Rob
This script does everything internally. You might want to tweak the way it loops to more robustly handle short input strings. I'm not sure what your restriction about iteration means.
#!/bin/bash
set -f
VAR="cyrus:*:77:6::0:0:Cyr
TMP=$VAR
for i in 0 1 2 3 4 5 6 7 8 9; do
RES[$i]=${TMP%%:*}
TMP=${TMP#*:}
done
echo res[3] is ${RES[3]}
echo "\$VAR is $VAR"
echo -n "\$RES is:"
for i in ${RES[@]} ; do
echo -n " '$i'"
done
echo
I awarded an A grade to rjkimble's read using HERE i/o redirection because:
- it is simple and elegant
- it uses a built-in to do the splitting
- it doesn't iterate calling external commands
I give additional points to glassd, for suggesting cut -d: (which I made use of elsewhere),
and Jeff_2 for pointing out that id -P won't work on my target platform (I now grep /etc/passwd).
Thank you all for your help.
Business Accounts
Answer for Membership
by: da99rmdPosted on 2004-07-13 at 09:46:15ID: 11540748
Hi brettmjohnson, int $1,$2,$3,$4,$5,$6,$7}' | sed 's/ /KALLEKOSKIT/g' | sed 's/,/ /g'`)
here is a solution i have used in some scripts maybe there is a better one:
array=(`id -P cyrus | awk 'BEGIN{FS=":";OFS=",";}{pr
this will give you the string KALLEKOSKIT as a " " sign.
so when you use the string just use this command
echo `echo $array[4] | sed 's/KALLEKOSKIT/ /g'
i hoped it helped.
/Rob