Click to See Complete Forum and Search --> : Bash script question


Sawdusty
10-24-2002, 11:38 AM
Hello,

I've managed to get a variable to contain data of the form:

loginname: real Name
loginname: real Name
loginname: real Name
.
.
.

if I echo "$varname" it shows that it contains the right information.

Now I need to know how I can access each line in a loop, then access the login Name and finally the real name (eventually I want to send mail to the user). For now, could somebody tell me how to get working code something like the following:

for something or other loop ; do
login=howdo I get the login name from the line
realname=how do I get the real name
echo "login $login real name: $realname"
done

If I can get past that, I thnk I can do the rest on my own.

Thanks,

Dusty

mrBen
10-24-2002, 11:46 AM
You'll need to use some sort of regexp to extract everything up to the : and then everything after the colon on the line.

Should be easy for someone who knows anything about regexps, which isn't me.

z0mbix
10-24-2002, 12:03 PM
I don't know exactly what you are trying to do but does $varname contain just one name or more?

Is this what you are after?:

for name in "${varname[@]}"; do
echo $name
done

l01yuk
10-25-2002, 05:33 AM
I think you want to use a while loop since for loops take input per field and while loops per line.

Try

echo "$varname" |
while read NAME
do
REAL_NAME=`cut -d: -f2`
<operation on the real name>
done

I am assuming of course that $varname contains newline characters.

furrycat
10-25-2002, 06:22 AM
If you've been paying attention you'll see that I've made three posts and deleted them when I realised that what I'd written wasn't right :)

If you can extract individual lines and store them in $line, you can do thisloginname=${line%%:*}
realname=${line#*:}. Extracting the lines is the hard part. Well actually it isn't but I forgot how to do it and now I gotta go :rolleyes:

d3k4y
10-25-2002, 10:39 AM
Simplest way I find is a simple (g)awk one-liner. Clear and concise and easy to debug later.

you've got, say, LINE=fred:bill

fred_var=`echo ${LINE} | awk -F':' '{print $1}'`
bill_var=`echo ${LINE} | awk -F':' '{print $2}'`

echo ${fred_var}
echo ${bill_var}

The hardest part should be iterating through the lines in the variable coz of IFS issues when doing:

for LINE in ${MY_LINES}
do
done

Hope helps.

Sawdusty
10-25-2002, 04:42 PM
Thanks for all the replies. I like being able to pick and choose. :-D

I eventually got it to work using this syntax:

echo "$birthdays" |
while read LINE ; do
loginname=$(echo "$LINE" | awk -F':' "{print \$1}")
realname=$(echo "$LINE" | awk -F':' "{print \$2}")
echo $loginname
echo $realname
done


could anybody explain how the syntax posted by furrycat was supposed to work:

loginname=${line%%:*}
realname=${line#*:}

It didn't work for me when I tried it. However, I'd like to know why it didn't work, or more specifically how it should work. It looks like a default-value assignment, but what do the %, #, and * do in that context?



Also, I've got another question. I would like to have my script add itself to the at queue. In order to do that, I should know the full path to the script. How can I do that?

In other words, I'm kinda looking for the opposite of basename.

Thanks for all the help. :)

Dusty

yosarian
10-30-2002, 02:46 PM
I'm very green to Linux, so take this for what you will . . .
The opposite of basename should be dirname, e.i.:

dirname /home/usr/images/foo.jpg will return
/home/usr/images

As for the string chopping in furrycat's post, check out this site http://www-4.ibm.com/software/developer/library/bash.html. It explains it really well.

It's the first of 3 bash scripting tutorials written by Daniel Robbins, who at the time (and may still be) CEO of Gentoo Technologies. Hope this helps.

Sawdusty
10-30-2002, 07:46 PM
Thanks. That helped a lot. :)

Dusty

bwkaz
10-30-2002, 11:46 PM
Originally posted by Sawdusty
Also, I've got another question. I would like to have my script add itself to the at queue. In order to do that, I should know the full path to the script. How can I do that? Why not just use cron?

If you want to go with at, though, $0 is "the full name of the current program". It doesn't expand directories, though (if you run it with "./script", then $0 will be exactly that, ./script, but that should work for at as long as the script was run from at to begin with).

Sawdusty
10-31-2002, 02:54 PM
Originally posted by bwkaz
Why not just use cron?


Umm... because I don't know how. :D

I'll read the man page. I thought they did the same thing, actually.

I knew what $0 did, but I was afraid that if I added it to at, and then logged out, it wouldn't be able to find it. My solution so far is to use basename $0 and then make sure that the script is in the path.

Dusty

bwkaz
11-01-2002, 02:12 PM
Oh, cron isn't bad. Just run a crontab -e to open up an editor on your crontab file, and have the man page for crontab(5) open somewhere else (either another terminal, or another console). The basic syntax is:

<minute> <hour> <day of month> <month of year> <day of week> <script to run>

All of these are normally numbers, or * to mean "all". You can also use /<number> to mean "every number" units of time in the range. So if I had "0-59/20" in the minute field, the script would run once each time the "minute" part of the system clock was divisible by 20; in other words, 3 times every hour.

<script to run> is just the command that starts up your script.

The reason I'd go with cron instead is that cron repeats its tasks, whereas at just does them once and forgets about them. It sounds like you need to repeat whatever you're doing.