LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 02-05-2004, 02:06 AM   #1
Software
LQ Newbie
 
Registered: Jan 2004
Posts: 25

Rep: Reputation: 15
simple Shell program for pro's ..but need some help


Hi all .. i'm having these qustions in one of the assignment at school , and i'm stuck at some point

I know i might have dome a terouble mistakes in both specially the first one there is lots of stuff missing , but i'm just a begginer and i don'n know how to solve that , and the assignment is really worth it !! it's 10% of the final grade !! know what i mean !!

i'd really apprecaite the help , coz i have to hand it in after about 12 hours !!

the programs have to be in ( sh )

the first questions says :
-------------------------------------------------------------------------------------------------------------------------------------
Comment counter
Your shell script called comcount should take 1 or more arguments: the names of text files to check.
For example: comcount *.c

The program should open argument in turn and count the number of comments, i.e lines containing the strings either // or /*. Note: modification, you need not deal with C++ coments of the form '//'. Note that you are supposed to count the number of comments, not the number of lines of comment text. In your documentation you should comment on the difference between these alternative goals.

As extra features, you should count: the number of words of comment text, and the number of unique words of comment text. (Note: as discussed in class, you do not need to count the number of lines of comment text.)

Your program output should be a set of lines each containing a file name followed by a number, exactly as follows. Make sure your default output follows this format exactly.

e.g.

% comcount foo.c
foo.c
13
98
11

where these are the number of comments (13 in this case), the number of the number of words (98) and the number of unique words (11)
---------------------------------------------------------------------------------------------------------------------------------------
and this is the code i wrote for it is :

#/bin/sh
echo Enter the name of the file :
read cFile > file1
cat file1 > temp
num=0
set -f
for i in temp
do
if (i == /*)
then
num=`expr $num + 1`
fi
done
echo $num
wc -w temp
uniq -c temp
rm temp file1
---------------------------------------------------------------------------------------------------------------------------------------
and the second questions is :

File mod checker

Write and test a shell script called checker that is supposed check if any files in a directory have been modified, without making duplicate copies of them. The idea is to compute a checksum (using cksum) for each file and save these checksums in one special file within the directory. When the program is executed, if any file has a different or missing checksum, the name of the file is reported and a copy of the file is saved in a ``tarball'' (discussed in class)/ Save your archived data in a director called "Backups". One futher subtlety is that you should skip the calculation for any file whose name ends in .var or .tar or .z
---------------------------------------------------------------------------------------------------------------------------------------
and the code i wrote for it is :

#!/bin/sh

if (ls * | grep tarball.tar )
then
cksum * > file1
cat file1 | grep -v '*.tar' | grep -v '*.Z' | grep -v '*.var' | grep -v temp1 | grep -v checksums | grep -v file1 | grep -v tarball.tar > temp1
rm file1

if (!(diff checksums temp1 > /dev/null))
then
diff checksums temp1 > difference
#cat temp1 > checksums
cat difference | tr -d '[0-9-]' | cut -b 3- > tp
sort tp | uniq > name
cat name
for i in `cat name`
do
tar -rf tarball.tar $i
done
rm tp
rm difference
rm name
cat temp1 > checksums
fi
rm temp1

else
cksum * > file1
cat file1 | grep -v '*.tar' | grep -v '*.Z' | grep -v '*.var' | grep -v file1 > checksums
ls * | grep -v '*.tar' | grep -v '*.Z' | grep -v '*.var' | grep -v file1 | grep -v checksums > temp2
for i in `cat temp2`
do
tar -rf tarball.tar $i
done
echo The files are backed up and no things have been made
# rm file1 temp2
fi
---------------------------------------------------------------------------------------------------------------------------------------

Thanks alot , i really appreciate any help ..

Last edited by Software; 02-05-2004 at 04:27 AM.
 
Old 02-05-2004, 11:02 AM   #2
Software
LQ Newbie
 
Registered: Jan 2004
Posts: 25

Original Poster
Rep: Reputation: 15
.
 
Old 02-06-2004, 01:27 AM   #3
AMMullan
Member
 
Registered: Sep 2003
Location: United Kingdom
Distribution: Ubuntu, Arch
Posts: 438

Rep: Reputation: 30
K i've been playing with the 1st one (sorry, just found your post) and this is what I have so far:

Code:
#! /bin/bash
                                                                                                   
echo -n "Enter the name of the file: "
read FILE
                                                                                                   
  COMM_COUNT=`cat $FILE | grep "/*" | wc -l | awk '{print $1}'`
  WORD_COUNT=`cat $FILE | wc -w | awk '{print $1}'`
                                                                                                   
echo -n "Amount of comments: "
  echo "$COMM_COUNT"
echo -n "Amount of words: "
  echo "$WORD_COUNT"
I'm unsure of how to get a count of uniq lines ( i tried your method, uniq -c foo.c, but it doesn't seem to work, just print the file with a 1 on the front...)

I'll play with the 2nd one and see what I can do
 
Old 02-06-2004, 10:04 AM   #4
Software
LQ Newbie
 
Registered: Jan 2004
Posts: 25

Original Poster
Rep: Reputation: 15
Thanks for replying

actually in the first question , you are supposed to count the words of the comment , not the words of the file , i tried to write some thing , but i don't know what's wrong with it , it seems to have some syntax error ,
anyway for counting the words there should be some thing that starts reading the words after the first comment sign /* and writing these words to file , and after that we put like an if statment that stops writing to the file when it sees */ which is the end of the comment ..
and for the uniq words ,, it will get the uniq words of this file that we created ( not the file given , we need the uniq words in the comment )
programing in shell is just so effective and so stupid in the same time , i mean you'll get an error some times , just because you added a space !!
this kills me

can i ask you some thing , what does (awk) do ?
 
Old 02-06-2004, 05:16 PM   #5
AMMullan
Member
 
Registered: Sep 2003
Location: United Kingdom
Distribution: Ubuntu, Arch
Posts: 438

Rep: Reputation: 30
I only have a litle knowledge of awk (it is a very powerfult tool but one I haven't had time to learn properly). I use it to filter words:

Code:
$: echo "The quick brown fox" | awk '{print $1}'
The

$: echo "The quick brown fox" | awk '{print $3}'
brown

$: echo "The quick brown fox" | awk '{print $2 $3}'
quickbrown

$: echo "The quick brown fox" | awk '{print $3 " " $4}'
brown fox
as for your problem: try putting a set -x at the very start of your script - that will show you in detail where the script is going wrong...

Let me know how ya go
 
Old 02-06-2004, 06:42 PM   #6
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 59
This should get you started.....

Code:
#!/bin/bash

#find the lines which start and end with "/*"
#remove the "/*" from output
cat /home/text.txt |grep ^[\/][\*] | sed -e 's/^.\{2\}\(.*\).\{2\}$/\1/' > file.txt

#count the number of lines which start and end with "/*"
cat /home/file.txt |wc -l > file1.txt

#count the number of words from the lines that start and end with "/*"
cat /home/file.txt |wc -w >> file1.txt

#count the number of unique words which are from the comment lines.
cat /home/file.txt | tr ' ' '\012' |sort | uniq |wc -l >> file1.txt

Last edited by homey; 02-06-2004 at 07:55 PM.
 
Old 02-06-2004, 07:12 PM   #7
AMMullan
Member
 
Registered: Sep 2003
Location: United Kingdom
Distribution: Ubuntu, Arch
Posts: 438

Rep: Reputation: 30
Good one homey

Didn't even think about tr'ing the blank spaces - and now I know how to use uniq...

Cheers
 
Old 02-06-2004, 07:20 PM   #8
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 59
Hope that's something like what he had in mind. It was fun.
 
Old 02-07-2004, 04:18 AM   #9
Software
LQ Newbie
 
Registered: Jan 2004
Posts: 25

Original Poster
Rep: Reputation: 15
AMMullan thanks for explaining some of the awk work ..

wow homey .. quite nice and brief !! I guess my code now looks so stupid
.. well.. i admit it , it was !! hehe

but i didn't really understand what was going on in this part

grep ^[\/][\*] | sed -e 's/^.\{2\}\(.*\).\{2\}$/\1/'

here grep is " greping " what ?? and what does sed do , with all these arguments ? it helped solving the problem quite fast and efficient , do you mind explain it a little ..

and in the translation code : tr ' ' '\012'
i didn't get why you put them ..


thanks alot ,, i really enjoy learning this stuff .. it just makes you feel so powerful , doesn't it ?
actually i am a microsoft windows user , but now that i know linux , i think there is no way of comparing the two , in terms of having kinda control over your system , and getting more to the core of the real stuff , not just a " human machien who knows how to deal with the " that's it - programs "

thanks for the help .. and waiting to have more fun with the second one .. if you guys suggest working on some thing that is not hard for

i would love to do it ..
 
Old 02-07-2004, 05:05 AM   #10
AMMullan
Member
 
Registered: Sep 2003
Location: United Kingdom
Distribution: Ubuntu, Arch
Posts: 438

Rep: Reputation: 30
K well i'll help explain a little (kinda forgotten some stuff due to learniing C)

the tr ' ' '\012' just replaces every instance of whitespace with a new line (tr ' ' '\n' would've worked too)..

As for the grep ^[\/][\*] | sed -e 's/^.\{2\}\(.*\).\{2\}$/\1/'... I couldn't explaing it as clearly as I used to so i'll leave that for homey

If you want to see an example of a server "monitor" let me know, as i've written one in bash (uses nmap, very kewl script that took a while when i was a newbie)
 
Old 02-07-2004, 10:34 AM   #11
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 59
I'll try to explain.

grep ^[\/][\*] | sed -e 's/^.\{2\}\(.*\).\{2\}$/\1/'

grep ^[\/][\*] ......
grep.... search for an item which I will determine.
The carrot ( ^ ) says the item is at the beginnng of any line.
[\/] This was a problem as the "/*" are special characters used by the program. Therefore instead of using a normal term like grep "frog" , I had to add the "\" to make the program ignore them. I had to use "/" and "*" separately in case there is a line in your text which just starts with a "/" .

The pipe ( | ) just sends stuff on over the next command which is sed
's/^.\{2\}\(.*\).\{2\}$/\1/'
Here we use s to substitute one item for another on each of the lines that grep found for us. The comment lines start and stop with comments which you don't want counted as words. Therefore we use sed ( streaming editor ) to get rid of those comments ( /* ) before sending our line to the temporary file.
So use the carrot ( ^ ) to find something at the beginning of the line. In this case exactly two characters of any kind .\{2\}. We can say any kind because grep already found the line and we know it starts with "/*" .
The next part \(.*\) includes any part of the line which comes after the first two charaters.
The next part .\{2\}$ defines exactly two characters at the end of the line. We use the ( $ ) to say end of line.
/\1/ This would probably be less confusing if you had some spaces in there like this "/ \1 /" . Remember you are doing substitution. What gets substituted is a complete line goes to a line with two characters chopped of from the start and end.
So this part \1 is the body of text in that line. The other stuff is just not added here and that is how you drop it.

I hope that clears it up a bit
 
Old 02-07-2004, 05:52 PM   #12
AMMullan
Member
 
Registered: Sep 2003
Location: United Kingdom
Distribution: Ubuntu, Arch
Posts: 438

Rep: Reputation: 30
Ummm homey, i just ran it on the project i'm orking on and it ONLY comes up with the commented lines that start with /* - what happens if he has a line with a comment half-way thru? Also it only show the 1st line of the comment...

I'll have a play aswell - it's so kewl seeing the power of sed

Last edited by AMMullan; 02-07-2004 at 05:53 PM.
 
Old 02-07-2004, 06:53 PM   #13
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 59
Argh!!!!! sorry to say I didn't test that good enough.
You could smack the program writer and tell them to put comments at the beginning of the line or you could try this....

Code:
#!/bin/bash

#find the lines which start and end with "/*"
#remove the "/*" from output
cat /home/text.txt |grep '[\/][\*]\(.*\)[\/][\*]' | \
awk -F[\/][\*]  '{print $2}' > file.txt

#count the number of lines which start and end with "/*"
cat /home/file.txt |wc -l > file1.txt

#count the number of words from the lines that start and end with "/*"
cat /home/file.txt |wc -w >> file1.txt

#count the number of unique words which are from the comment lines.
cat /home/file.txt | tr ' ' '\012' |sort | uniq |wc -w >> file1.txt
 
Old 02-07-2004, 06:56 PM   #14
Looking_Lost
Senior Member
 
Registered: Apr 2003
Location: Eire
Distribution: Slackware 12.0, OpenSuse 10.3
Posts: 1,120

Rep: Reputation: 45
if you want a directiory listing exclunding certain types you can do

dirListing=`find /myfile/directory -type f ! -name *.tar ! -name *.z ! -name ! -name *.var`

then basename to get the pure names of the files.

Last edited by Looking_Lost; 02-07-2004 at 06:59 PM.
 
Old 02-08-2004, 10:08 AM   #15
homey
Senior Member
 
Registered: Oct 2003
Posts: 3,057

Rep: Reputation: 59
Quote:
If you want to see an example of a server "monitor" let me know, as i've written one in bash (uses nmap, very kewl script that took a while when i was a newbie)
Hey AMMullan,
Let's see that script if you don't mind.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Problems compiling a simple shell program yekrahs Programming 3 09-26-2005 01:07 PM
simple shell script sharpie Programming 9 06-03-2004 12:47 AM
simple shell script Greg_courageous Programming 2 05-12-2004 05:34 PM
Simple Bash Shell Program frankblack Programming 2 02-15-2003 12:59 AM
Simple C Shell script is not so simple elconde Programming 2 09-17-2001 12:53 AM


All times are GMT -5. The time now is 08:14 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration