Operating System - Linux
1828471 Members
3035 Online
109978 Solutions
New Discussion

Stripping out a character to use again...

 
SOLVED
Go to solution
RobinKing
Valued Contributor

Stripping out a character to use again...

I trying to create a simple script to add some users. Usernames are listed in /tmp/file, each line is formed like a12345, I want the numeric characters to form the UID.

I've been playing around with different things but can't get it to do exactly what I want.

for i in `cat /tmp/file`
do
USERNAME=$i
UID=$USERNAME | cut -c2-6

done

$UID reports back blank.

"cat /tmp/file | cut -c2-6" gives me the output I want for $UID but I can't translate this into something that will work in the shell script.

Thanks!
12 REPLIES 12
Dennis Handly
Acclaimed Contributor
Solution

Re: Stripping out a character to use again...

UID=$USERNAME | cut -c2-6

You need to send output to the pipe:
UID=$(echo $USERNAME | cut -c2-6)
RobinKing
Valued Contributor

Re: Stripping out a character to use again...

Thanks, spot on!
Dennis Handly
Acclaimed Contributor

Re: Stripping out a character to use again...

I think a shell only solution to strip the first char would be:
UID=${USERNAME#?}
RobinKing
Valued Contributor

Re: Stripping out a character to use again...

Thanks Dennis. I've just realised I've forgotten about the Comment field that'll I'll need.
If I add a second field to /tmp/file:

a12345:Joe Bloggs,Somewhere,,

Can you suggest how I can set a COMMENT variable? Taking into account I'll need to quote it with "blah blah"

Thanks
James R. Ferguson
Acclaimed Contributor

Re: Stripping out a character to use again...

Hi Robin:

You could do something like this:

#!/usr/bin/sh
while read LINE
do
UID=`echo ${LINE}|awk -F":" '{print substr($1,2,6)}`
WHO=`echo ${LINE}|awk -F":" '{split($2,a,/,/);print a[1]}'`
CMT=`echo ${LINE}|awk -F":" '{split($2,a,/,/);print "\""a[2]"\""}'`

echo ${UID}
echo ${WHO}
echo ${CMT}
done < /tmp/file

...Note that I echoed the resulting fields only for demonstration purposes.

Notice too, that I eliminated the extra process (the 'cat') and let the shell open the file and read it directly.

Regards!

...JRF...
RobinKing
Valued Contributor

Re: Stripping out a character to use again...

Thanks James, this thread will be very useful reference for the future.

For future reference, and just to close the thread, the finished script looks like:

#!/usr/bin/sh
cat /tmp/file
while read LINE
do
UID=`echo ${LINE}|awk -F":" '{print substr($1,2,6)}`
USER=`echo ${LINE} | awk -F":" '{print substr($1,1,6)}`
CMT=`echo ${LINE}|awk -F":" '{split($2,a,/,/);print "\""a[1]", "a[2]"\""}'`

useradd -u ${UID} -g -c ${CMT} -d -s /usr/bin/sh ${USER}
RobinKing
Valued Contributor

Re: Stripping out a character to use again...

Of course, with "done" to complete the loop.
Dennis Handly
Acclaimed Contributor

Re: Stripping out a character to use again...

>Of course, with "done" to complete the loop.

If you look closely at JRF's loop, you need to remove your cat (that's not on the same line as the while), and then change your done to:
done < /tmp/file
RobinKing
Valued Contributor

Re: Stripping out a character to use again...

This is what I ended up with:

#!/usr/bin/sh
set -x
cat /tmp/file
while read LINE
do
UID=`echo ${LINE}|awk -F":" '{print substr($1,2,6)}`
USER=`echo ${LINE} | awk -F":" '{print substr($1,1,6)}`
WHO=`echo ${LINE}|awk -F":" '{split($2,a,/,/);print a[1]}'`
CMT=`echo ${LINE}|awk -F":" '{split($2,a,/,/);print "\""a[1]", "a[2]"\""}'`

/usr/sbin/useradd -u ${UID} -g 2005 -c ${CMT} -d -s ${USER}
/usr/lbin/modprpw -x ${USER}

done < /tmp/file

Dennis, do I need to alter that?
I'm not getting the results I'd expect. It seems to pick up the variables fine, but running the script produces a "To many arguements" error from the useradd.
Set -x echo's the correct syntax for the useradd, and if i were to cut and paste that to the command line and run it, it works.

Take out the -c and the script would work, so I'm presuming it's something to do with the quotes.

+ cat /tmp/helpusers
a12345:Joe Bloggs,Helpdesk,,
+ 0< /tmp/file
+ read LINE
+ + echo a12345:Joe Bloggs,Helpdesk,,
+ awk -F: {print substr($1,2,6)}
UID=12345
+ + echo a12345:Joe Bloggs,Helpdesk,,
+ awk -F: {print substr($1,1,6)}
USER=a12345
+ + echo a12345:Joe Bloggs,Helpdesk,,
+ awk -F: {split($2,a,/,/);print a[1]}
WHO=Joe Bloggs
+ + echo a12345:Joe Bloggs,Helpdesk,,
+ awk -F: {split($2,a,/,/);print "\""a[1]", "a[2]"\""}
CMT="Joe Bloggs, Helpdesk"
+ /usr/sbin/useradd -u 12345 -g 2005 -c "Joe Bloggs, Helpdesk" -d /home/a12345 -s /usr/bin/sh a12345
Too Many Arguements specified
Usage: /usr/sbin/useradd [-u [-o]] [-g ] [-G [,]] [-d ] [-s ] [-c ] [-m [-k &lt;skel&lt;BR /&gt; dir&gt;]] [-f &lt;inactive&gt;] [-e &lt;expire&gt;] [-r &lt;yes|no&gt;] &lt;login&gt;&lt;BR /&gt;Usage: /usr/sbin/useradd -D [-g &lt;group&gt;] [-b &lt;base dir&gt;] [-f &lt;inactive&gt;] [-e &lt;expire&gt;] [-r &lt;yes|no&gt;]&lt;BR /&gt;+ read LINE
Dennis Handly
Acclaimed Contributor

Re: Stripping out a character to use again...

cat /tmp/file

(I assume this is now just for debugging?)

>Dennis, do I need to alter that?

Well, given the usage of the archaic `` is an anathema to me and I'm on a mission to stomp them out... ;-)
You should replace them all by $(...):
UID=$(echo ${LINE}|awk -F":" '{print substr($1,2,6)})

>set -x echo's the correct syntax for the useradd, and if i were to cut and paste that to the command line and run it, it works.

That's the problem, it shouldn't work.
You need to do two things, remove the quotes from the variable assignment.
CMT=$(echo ${LINE}|awk -F":" '{split($2,a,/,/);print a[1] ", " a[2]}')

>Take out the -c and the script would work, so I'm presuming it's something to do with the quotes.

Exactly. Here is where you need the quotes:
... -c "${CMT}"

If you are dealing with quoting problems, you should really make a script that prints its args. You'll see that your script has:
+ printenv /usr/sbin/useradd -u 12345 -g 2005 -c "Joe Bloggs, Helpdesk" -d -s a12345
the count is 15
printenv
/usr/sbin/useradd
-u
12345
-g
2005
-c
"Joe
Bloggs,
Helpdesk"
-d

-s

a12345

And my script has:
+ printenv /usr/sbin/useradd -u 12345 -g 2005 -c Joe Bloggs, Helpdesk -d -s a12345
the count is 13
printenv
/usr/sbin/useradd
-u
12345
-g
2005
-c
Joe Bloggs, Helpdesk
-d

-s

a12345
Dennis Handly
Acclaimed Contributor

Re: Stripping out a character to use again...

>You should replace them all by $(...):
UID=$(echo ${LINE}|awk -F":" '{print substr($1,2,6)})

Oops, this is why `` is bad. JRF gave you some examples that had mismatched '' around the awk program and you didn't get errors. But with $() you do:
itrc_awk_passwd.sh[10]: Syntax error at line 24 : `'' is not matched.

So the line above (and the others) should end like:
UID=$(echo ${LINE}|awk -F":" '{print substr($1,2,6)}')
James R. Ferguson
Acclaimed Contributor

Re: Stripping out a character to use again...

Hi (again) Robin:

Yes, sorry, as Dennis noted, I dropped a closing single quote from 'awk'.

It is indeed interesting that the use of the backtick (grave accent) in the context of this syntax error isn't detected, whereas the POSIX $(...) syntax exposes the error.

Without starting a religous war, I would note that you should be familiar with both syntaxes :-)) As Dennis noted, the POSIX standard deprecates the use of the grave accents for command substitution.

Regards!

...JRF...