SunQuest
           UNIX Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsOperating SystemsUNIX Help

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
1200+ fellow developers rate and compare features of the top IDEs, like Visual Studio, Eclipse, RAD, Delphi and others, across 13 categories. Enjoy this FREE Download of the IDE User Satisfaction Study by Evans Data Corporation. Download Now!
  #1  
Old November 25th, 2004, 07:33 AM
Otts21 Otts21 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Posts: 14 Otts21 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 58 m 10 sec
Reputation Power: 0
Case Statement

I'm real new to unix scripts. Here's my problem.

I have a text file that holds data in the format of:

DON RENTA
DON RENTA
EON RENTA
XON RENTANT
ETC....

I am trying to run through each line of the data, cut out the first letter, compare it in a case and count the number of times each letter appears. So far I have:

a=0
while read line
do
a=`cut -c1`
case $a in
D)echo $a;;
*) ;;
esac
done < temp.txt

This produces no output. To test to make sure that my variables work and that the while loop works i changed it to:

a=0
while read line
do
a=`cut -c1`
case $a in
D);;
*)echo $a ;;
esac
done < temp.txt

and it printed out the first letter of each row even if the letter was D. So i can only assume that the issue is my case does not compare a$ and D as being true. If i can get this fixed I am sure that I can do the counting very easily. Is there a glaring mistake that I am missing?

Thanks in advance.

Reply With Quote
  #2  
Old November 25th, 2004, 09:22 AM
guggach guggach is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Jul 2004
Location: Middle Europa
Posts: 1,083 guggach User rank is Corporal (100 - 500 Reputation Level)guggach User rank is Corporal (100 - 500 Reputation Level)guggach User rank is Corporal (100 - 500 Reputation Level)guggach User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 4 Days 19 h 49 m 57 sec
Reputation Power: 9
your way: a=`echo $line | cut -c1`
my way: forgot all that, use an oneliner, try
sed -n 's/^\([^D]\).*/\1/p' inputfile

Reply With Quote
  #3  
Old November 25th, 2004, 09:51 AM
Otts21 Otts21 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Posts: 14 Otts21 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 58 m 10 sec
Reputation Power: 0
Thanks. Both work and I even understand the first one. My problem now is counting. I took :

case $a in
D) echo $a;;

and changed it to

case a$ in
D) count=`expr $count +1`;;

but when i echo $count it is zero.

Reply With Quote
  #4  
Old November 25th, 2004, 11:07 AM
M.Hirsch M.Hirsch is offline
Contributing User
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Oct 2000
Location: Back in the real world.
Posts: 5,969 M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Month 1 Day 22 h 39 m 55 sec
Reputation Power: 184
Another solution without the need for external programs:
Code:
case "$a" in
D*) count=`expr $count +1`;;

1. Note: the asterisk. It works like file system wildcards (not regexp)
2. Is your shell "bash"? You can write most scripts in bash without the need for any external programs, eg. count=$((count+1))
3. If portability is an issue, you should use "sed", "cut" and "expr". They are available by default on most (all?) unices. Bash is not.

...
Your $count is probably zero because "expr" wants a space betwen the "+" and the numbers on each side.

hth,
M.
__________________
--
Manuel Hirsch - Linux, FreeBSD, programming, administration articles, tutorials and more.

Reply With Quote
  #5  
Old November 25th, 2004, 12:01 PM
Otts21 Otts21 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Posts: 14 Otts21 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 58 m 10 sec
Reputation Power: 0
Thanks. But there still seems to be a problem somewhere. The full code is:

Code:
count=0
while read line
do
a=`echo $line | cut -c1`
case $a in
  D)count=`expr $count + 1`;;
  *);;
esac
done < temp.txt
echo $count


But all i get at the end is an ouput of 0 when i know the output should be in the 100's.

Reply With Quote
  #6  
Old November 25th, 2004, 12:10 PM
M.Hirsch M.Hirsch is offline
Contributing User
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Oct 2000
Location: Back in the real world.
Posts: 5,969 M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level)M.Hirsch User rank is First Lieutenant (10000 - 20000 Reputation Level) 
Time spent in forums: 1 Month 1 Day 22 h 39 m 55 sec
Reputation Power: 184
Quote:
Originally Posted by Otts21
Thanks. But there still seems to be a problem somewhere.
[...]
But all i get at the end is an ouput of 0 when i know the output should be in the 100's.

Odd. The script works fine for me... Maybe a permissions issue or search path now?

Reply With Quote
  #7  
Old November 25th, 2004, 07:37 PM
Perderabo Perderabo is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2003
Posts: 121 Perderabo User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 9 m 54 sec
Reputation Power: 5
Whether or not that code will work depends on the shell used to run it. With a modern shell like ksh it should work.

But the old bourne shell will place the while statement in a subshell. The changes the the count variable will be lost when the subshell exits.

Reply With Quote
  #8  
Old November 26th, 2004, 03:05 AM
guggach guggach is offline
Contributing User
Dev Shed Beginner (1000 - 1499 posts)
 
Join Date: Jul 2004
Location: Middle Europa
Posts: 1,083 guggach User rank is Corporal (100 - 500 Reputation Level)guggach User rank is Corporal (100 - 500 Reputation Level)guggach User rank is Corporal (100 - 500 Reputation Level)guggach User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 4 Days 19 h 49 m 57 sec
Reputation Power: 9
Q to Otts21, is that

A) an exercise to play with shell OR
B) a production issue ?

case A i propose:

for line in `cat inputfile`
do
case $line in D*) count=`expr $count + 1` ;; continue ;; esac
printf "%.1s\n",$line # not tested, should work, my *nix is down
done

case B:

# prints first char of each line NOT starting by D
sed -n 's/^\([^D]\).*/\1/p' inputfile

# counts lines starting by a D
grep -c '^D' inputfile


sure, this way open twice 'inputfile' for reading, but 'sed' and 'grep' are very
performat 'c' progs, this combination will be faster then every shell.

finally, if you want do the job in a ONEloop, use perl or 'c'
awk is also a possibility, but on large inputfile it will be slow.

Reply With Quote
  #9  
Old November 26th, 2004, 09:12 AM
Otts21 Otts21 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Posts: 14 Otts21 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 58 m 10 sec
Reputation Power: 0
Quote:
But the old bourne shell will place the while statement in a subshell. The changes the the count variable will be lost when the subshell exits.


This would be my problem then. I made a change to:
Code:
while read line
do
a=`echo $line | cut -c1`
case $a in
  D)count=`expr $count + 1`; echo $count;;
  *);;
esac
done < temp.txt
echo $count

When i run the script now it counts all the way up and then when the while loop is finnished resets the variable and prints 0.

example:
1
2
3
4
5
6
7
0


Is there a way to get the number in the variable out of the loop?

Reply With Quote
  #10  
Old November 26th, 2004, 09:32 AM
Perderabo Perderabo is offline
Contributing User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2003
Posts: 121 Perderabo User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 9 m 54 sec
Reputation Power: 5
Quote:
Originally Posted by Otts21
Is there a way to get the number in the variable out of the loop?


"Stop using an antique shell" comes quickly to mind.

Or write the value of count into a temporary file each iteration of the loop. Outside the loop, read the file to get the value. This is not as terrible as it sounds due to the unix buffer cache. But it's not an ideal solution either.

What OS are you using? If it's Solaris, ksh is available.

Reply With Quote
  #11  
Old November 26th, 2004, 09:42 AM
Otts21 Otts21 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Nov 2004
Posts: 14 Otts21 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 4 h 58 m 10 sec
Reputation Power: 0
Well i sent it to a file and overwrote that file until the loop was done. Then cat file to screen. It works. Unfortunatly I am not able to use any other shell as this is at work and is all i have access to.

Thank you everyone for your help.

Reply With Quote
Reply

Viewing: Dev Shed ForumsOperating SystemsUNIX Help > Case Statement


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway