Hey guys - i am working off three files that contain information on associates and their sales.
The files are:

products: (product ID, name, price item)
% cat products
103:sway bar:49.99
101ropeller:104.99
104:fishing line:0.99
...
108:wheel:49.99
111:lock:31.00
102:trailer hitch:97.95

sales: (product ID,num. sold, date sale, associate ID)
% cat sales
110,1,01:02:2007,22
110,2,02:02:2007,23
109,1,03:03:2006,24
104,2,03:02:2007,24
...
104,2,05:03:2007,24
112,1,05:03:2007,23
104,9,05:03:2007,21

associates: (associate ID, name, salary, position)
% cat associates
21/John Doe/39000/Clerk
22/George Bush/99000/President
23/Susan Worker/44000/Manager
24/Fast Buck/21000/Stock Boy
25/Hillary Clinton/99000/Candidate
26/Dennis Miller/88000/Commedian

The output needs to come out something like:
$ ./report.sh
Name Position Sales Amount
========================================
Fast Buck Stock Boy 2712.77
George Bush President 1059.67
Susan Worker Manager 399.52
John Doe Clerk 284.74
Hillary Clinton Candidate 151.00
Dennis Miller Commedian 2.97

command line command: ./report.sh

I have done the following to start -

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales.$$

COUNTER=21
while [ $COUNTER -le 26 ]
do
        awk '$1 == $COUNTER {print $0}' /tmp/newSales.$$ > /tmp/sales.$COUNTER.$$
        echo "SALES FOR ASSOCIATE $COUNTER"
        cat /tmp/sales.$COUNTER.$$
        let COUNTER=$COUNTER+1
done

#Below removes all created files
rm /tmp.newSales.$$
i=21
while [ $i -le 26 ]
do
        rm /tmp/sales.$COUNTER.$$
        let i=$i+1
done

As i hope you can see - what i want to do is to go through each associate (numbered 21-26) and take their sales and store it into their own sales file.

The first line i have makes sure that ONLY sales from 2007 are now in the sales file i will be working with ... does this make sense so far?

Is there a reason why the files though would end up being empty? Is there something i am overlooking? Thanks guys...

Recommended Answers

All 24 Replies

New attempt, slightly different..help?

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales.$$
LINES=`wc -l newSales.$$`
echo lines in file $LINES
COUNTER=21
while [ $COUNTER -le 26 ]
do
  COUNT=1
  while [ $COUNT -lt $LINES ]
     do
         awk '$4 == $COUNTER {print $0}' /tmp/newSales.$$ > /tmp/sales.$COUNTER.$$
         let COUNT=$COUNT+1
  done
        echo "SALES FOR ASSOCIATE $COUNTER"
        cat /tmp/sales.$COUNTER.$$
        let COUNTER=$COUNTER+1
done

#Below removes all created files
rm /tmp/newSales.$$
i=21
while [ $i -le 26 ]
do
#       rm /tmp/sales.$COUNTER.$$
        let i=$i+1
done

gets me this:


/home/lx/z109079 : ./report.sh
wc: newSales.21066: No such file or directory
lines in file
./report.sh: line 9: [: 1: unary operator expected
SALES FOR ASSOCIATE 21
cat: /tmp/sales.21.21066: No such file or directory
./report.sh: line 9: [: 1: unary operator expected
SALES FOR ASSOCIATE 22
cat: /tmp/sales.22.21066: No such file or directory
./report.sh: line 9: [: 1: unary operator expected
SALES FOR ASSOCIATE 23
cat: /tmp/sales.23.21066: No such file or directory
./report.sh: line 9: [: 1: unary operator expected
SALES FOR ASSOCIATE 24
cat: /tmp/sales.24.21066: No such file or directory
./report.sh: line 9: [: 1: unary operator expected
SALES FOR ASSOCIATE 25
cat: /tmp/sales.25.21066: No such file or directory
./report.sh: line 9: [: 1: unary operator expected
SALES FOR ASSOCIATE 26
cat: /tmp/sales.26.21066: No such file or directory


Hope this gets me closer to some help - answer or something else!

output from new script:


lines in file 25
SALES FOR ASSOCIATE 21
SALES FOR ASSOCIATE 22
SALES FOR ASSOCIATE 23
SALES FOR ASSOCIATE 24
SALES FOR ASSOCIATE 25
SALES FOR ASSOCIATE 26
rm: cannot remove `/tmp/sales.27.22499': No such file or directory
rm: cannot remove `/tmp/sales.27.22499': No such file or directory
rm: cannot remove `/tmp/sales.27.22499': No such file or directory
rm: cannot remove `/tmp/sales.27.22499': No such file or directory
rm: cannot remove `/tmp/sales.27.22499': No such file or directory
rm: cannot remove `/tmp/sales.27.22499': No such file or directory


script:

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales.$$
cat /tmp/newSales.$$
LINES=`wc -l /tmp/newSales.$$ | cut -c1-2`
echo lines in file $LINES
COUNTER=21
while [ $COUNTER -le 26 ]
do
  COUNT=1
  while [ $COUNT -lt $LINES ]
     do
         awk -F, '$4 == $COUNTER {print $1","$2","$3","$4}' /tmp/newSales.$$ >> /tmp/sales.$COUNTER.$$
         let COUNT=$COUNT+1
     done
        echo "SALES FOR ASSOCIATE $COUNTER"
        cat /tmp/sales.$COUNTER.$$
        let COUNTER=$COUNTER+1
done

#Below removes all created files
rm /tmp/newSales.$$
i=21
while [ $i -le 26 ]
do
        rm /tmp/sales.$COUNTER.$$
        let i=$i+1
done

why arent my associates.$COUNTER.$$ files being filled with any information - they should be filled with all sales for the associate number, so something like this for associate 21.
104,9,03:01:2007,21
111,4,12:02:2007,21
107,9,03:01:2007,21
104,9,03:03:2007,21
104,9,05:03:2007,21

and then the same for each associate (similar files - notice how the $4 is 21, thats the associates ID)

I think there is something wrong with my while statements - please let me know... thanks

Ok, I think this is roughly what you are looking for. You will still need to fine tune it to get the final answers you need. Some parts are hard coded, like assuming your associate id's range from 21 - 26. You might want to read those values in if you are trying to make something more generic. I hope this helps some.

Also, there is nothing wrong with your while loop. Your awk syntax is messed up.

What you are looking for, I think perhaps this ?

awk -F"," '/$COUNTER/ {print $0}' sales

#! /bin/bash

#generate a newSales file for each associate
ID=1
while [ $ID -le 6 ]
do
  awk /[2][$ID]/ sales > /tmp/newSales.$ID
  let ID=$ID+1
done

#read each associate file line by line, find the price
#for the product id sold by the associate. Assuming
#product id is in a file called product with records
#as follows '110.abc.22.13'
#compute total for each prod id using the quantity and
#price for the product
ID=1
while [ $ID -le 6 ]
do
  echo "SALES FOR ASSOCIATE 2$ID"
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QTY=`echo $line|cut -d"," -f2`
    PRICE=`awk /$PRODID/ product|awk -F"." '{print $3"."$4}'`
    TOTAL=$(echo "scale=2; $PRICE*$QTY" | bc)
    echo "Associate 2$ID made $TOTAL for selling $PRODID"
  done < "/tmp/newSales.$ID"

  let ID=$ID+1
done

#Below removes all temp files
rm /tmp/newSales*

I worked on what you said - and have come across a couple of problems ... first off i get errors while running the script:

/home/lx/z109079 : ./newtest.sh
./newtest.sh: line 25: unexpected EOF while looking for matching `"'
./newtest.sh: line 36: syntax error: unexpected end of file

Using this script:

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales.$$
#cat /tmp/newSales.$$
#LINES=`wc -l /tmp/newSales.$$ | cut -c1-2`
#echo lines in file $LINES

ID=1
while [ $ID -le 6 ]
do
  awk /[2][$ID]/ /tmp/newSales.$$ >> /tmp/sales.2$ID
  let ID=$ID+1
done

ID=21
while [ $ID -le 6 ]
do
  echo "SALES FOR ASSOCIATE 2$ID"
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QUANT=`echo $line|cut -d"," -f2`
    PRICE=`awk /$PRODID/ product|awj -F"." '(print $3"."$4}'`
    TOTAL=${echo "scale=2; $PRICE*QUANT" | bc)
    echo "Associate 2$ID made $TOTAL for selling $PRODID
    done < "/tmp/newSales.2$ID"

  let ID=$ID+1
done

# removes all created files
#rm /tmp/newSales.*

Also - i commented out the rm line at the bottom to see what, if anything was being stored in the sales.2$ID files within /tmp/ ... they all looked good except the sales for user ID 21 as shown below - for whatever reason, they include sales for associate 22 also - is this because some of associate 22's field are '21'??? That is the only reason i can see...

/home/lx/z109079 : cat sales.21
104,9,03:01:2007,21
111,4,12:02:2007,21
107,9,03:01:2007,21
108,21,03:02:2007,22
104,9,03:03:2007,21
104,9,05:03:2007,21
104,9,03:01:2007,21
111,4,12:02:2007,21
107,9,03:01:2007,21
108,21,03:02:2007,22
104,9,03:03:2007,21
104,9,05:03:2007,21
104,9,03:01:2007,21
111,4,12:02:2007,21
107,9,03:01:2007,21
108,21,03:02:2007,22
104,9,03:03:2007,21
104,9,05:03:2007,21


I really hope you can help me out some more - seems like im getting the hang of it and understanding it more and more -

Thanks again...

Your syntax errors are because of these 2 lines.

TOTAL=${echo "scale=2; $PRICE*QUANT" | bc)
echo "Associate 2$ID made $TOTAL for selling $PRODID

They should be (Need a ( bracket in line 1 and you have a missing quote in line 2)

TOTAL=$(echo "scale=2; $PRICE*$QUANT" | bc)
echo "Associate 2$ID made $TOTAL for selling $PRODID"

Also since you are only looking to isolate values based on the match the associate id, which in your case is luckily the final field :) . Try this instead (adds a $ at the end of the pattern to anchor it to the end of the line)

awk /[2][$ID]$/ /tmp/newSales.$$ >> /tmp/sales.2$ID

Hey - i fixed the things you mentioned and it seems to run - but now im getting slightly different errors and alot of them...


Associate 25 made for selling 112
(standard_in) 1: illegal character: Q
(standard_in) 1: illegal character: U
(standard_in) 1: illegal character: N
(standard_in) 1: illegal character: T
Associate 25 made for selling 111
(standard_in) 1: illegal character: Q
(standard_in) 1: illegal character: U
(standard_in) 1: illegal character: N
(standard_in) 1: illegal character: T
Associate 25 made for selling 112
(standard_in) 1: illegal character: Q
(standard_in) 1: illegal character: U
(standard_in) 1: illegal character: N
(standard_in) 1: illegal character: T
Associate 25 made for selling 111
(standard_in) 1: illegal character: Q
(standard_in) 1: illegal character: U
(standard_in) 1: illegal character: N
(standard_in) 1: illegal character: T
Associate 25 made for selling 112
(standard_in) 1: illegal character: Q
(standard_in) 1: illegal character: U
(standard_in) 1: illegal character: N
(standard_in) 1: illegal character: T
Associate 25 made for selling 111
SALES FOR ASSOCIATE 26
(standard_in) 2: illegal character: Q
(standard_in) 2: illegal character: U
(standard_in) 2: illegal character: N
(standard_in) 2: illegal character: T
Associate 26 made 0 for selling 104
(standard_in) 2: illegal character: Q
(standard_in) 2: illegal character: U
(standard_in) 2: illegal character: N
(standard_in) 2: illegal character: T
Associate 26 made 0 for selling 104
(standard_in) 2: illegal character: Q
(standard_in) 2: illegal character: U
(standard_in) 2: illegal character: N
(standard_in) 2: illegal character: T
Associate 26 made 0 for selling 104
(standard_in) 2: illegal character: Q
(standard_in) 2: illegal character: U
(standard_in) 2: illegal character: N
(standard_in) 2: illegal character: T
Associate 26 made 0 for selling 104
(standard_in) 2: illegal character: Q
(standard_in) 2: illegal character: U
(standard_in) 2: illegal character: N
(standard_in) 2: illegal character: T
Associate 26 made 0 for selling 104
(standard_in) 2: illegal character: Q
(standard_in) 2: illegal character: U
(standard_in) 2: illegal character: N
(standard_in) 2: illegal character: T
Associate 26 made 0 for selling 104
(standard_in) 2: illegal character: Q
(standard_in) 2: illegal character: U
(standard_in) 2: illegal character: N
(standard_in) 2: illegal character: T
Associate 26 made 0 for selling 104
(standard_in) 2: illegal character: Q
(standard_in) 2: illegal character: U
(standard_in) 2: illegal character: N
(standard_in) 2: illegal character: T
Associate 26 made 0 for selling 104

Script:

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales.$$
#cat /tmp/newSales.$$
#LINES=`wc -l /tmp/newSales.$$ | cut -c1-2`
#echo lines in file $LINES

ID=1
while [ $ID -le 6 ]
do
  awk '$4 == /[2][$ID]$/ {print $0}' /tmp/newSales.$$ >> /tmp/sales.2$ID
  let ID=$ID+1
done

ID=1
while [ $ID -le 6 ]
do
  echo "SALES FOR ASSOCIATE 2$ID"
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QUANT=`echo $line|cut -d"," -f2`
    PRICE=`awk /$PRODID/ products|awk -F"." '{print $3"."$4}'`
    TOTAL=$(echo "scale=2; $PRICE*QUANT" | bc)
    echo "Associate 2$ID made $TOTAL for selling $PRODID"
    done < "/tmp/sales.2$ID"

  let ID=$ID+1
done

# removes all created files
rm /tmp/newSales.*

I noticed i had a ( instead of a { around a print for awk and i mistyped awk awj ... fixed those and i still got the above errors - am i reading the wrong part of the file?

Any ideas? Ill try playing around with stuff - but am unsure about some of the codes u have written - i will look up such things as aw

You accidentally removed the $ before the QUANT. Put that back in, and you'll be fine.

commented: Very useful information +3

Yeah i noticed that - just changed it... and got this:


/home/lx/z109079 : ./newtest.sh
SALES FOR ASSOCIATE 21
SALES FOR ASSOCIATE 22
Associate 22 made 0 for selling 110
Associate 22 made 0 for selling 108
Associate 22 made 0 for selling 110
Associate 22 made 0 for selling 108
Associate 22 made 0 for selling 110
Associate 22 made 0 for selling 108
Associate 22 made 0 for selling 110
Associate 22 made 0 for selling 108
SALES FOR ASSOCIATE 23
Associate 23 made 0 for selling 110
Associate 23 made 0 for selling 112
Associate 23 made 0 for selling 110
Associate 23 made 0 for selling 112
Associate 23 made 0 for selling 110
Associate 23 made 0 for selling 112
Associate 23 made 0 for selling 110
Associate 23 made 0 for selling 112
Associate 23 made 0 for selling 110
Associate 23 made 0 for selling 112
Associate 23 made 0 for selling 110
Associate 23 made 0 for selling 112
Associate 23 made 0 for selling 110
Associate 23 made 0 for selling 112
Associate 23 made 0 for selling 110
Associate 23 made 0 for selling 112
SALES FOR ASSOCIATE 24
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0 for selling 113
Associate 24 made 0
0 for selling 104
Associate 24 made 0 for selling 105
Associate 24 made 0 for selling 109
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0 for selling 113
Associate 24 made 0
0 for selling 104
Associate 24 made 0 for selling 105
Associate 24 made 0 for selling 109
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0 for selling 113
Associate 24 made 0
0 for selling 104
Associate 24 made 0 for selling 105
Associate 24 made 0 for selling 109
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0
0 for selling 104
Associate 24 made 0 for selling 113
Associate 24 made 0

Very strange - and once again, no information for sales associate 21, he did sell somethings!

Haha - well deal with that once the addition part work!

It will be easier for you to debug this, if you break it up into smaller scripts to make sure each part is being done correctly.

A couple of things. $$ is usually the process id of -bash, so you may just want to use a file name like newSales, so that you have a constant. It'll be easier to check the contents while you're debugging.

Also this line

awk '$4 == /[2][$ID]$/ {print $0}' /tmp/newSales.$$ >> /tmp/sales.2$ID

If all you want to do is send particular associate id's to one file, this will suffice. Not sure if you want to append to the existing file or overwrite.

awk /[2][$ID]$/ /tmp/newSales.$$ > /tmp/sales.2$ID

Make sure you have the correct content in the sales.2$ID files. Then see that you get the correct product id, quantity and price for each record associated with the files, and do the total price calculations.

Try this.

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales
#cat /tmp/newSales.$$
#LINES=`wc -l /tmp/newSales.$$ | cut -c1-2`
#echo lines in file $LINES

ID=1
while [ $ID -le 6 ]
do
  awk /[2][$ID]$/ /tmp/newSales > /tmp/sales.2$ID
  let ID=$ID+1
done

ID=1
while [ $ID -le 6 ]
do
  echo "SALES FOR ASSOCIATE 2$ID"
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QUANT=`echo $line|cut -d"," -f2`
    PRICE=`awk /$PRODID/ products|awk -F"." '{print $3"."$4}'`
    echo $PRODID $QUANT $PRICE
    TOTAL=$(echo "scale=2; $PRICE*$QUANT" | bc)
    echo "Associate 2$ID made $TOTAL for selling $PRODID"
  done < "/tmp/sales.2$ID"

  let ID=$ID+1
done

# removes all created files
#rm /tmp/newSales.*

I changed some parts of the script to relect your changes...what is the best way to debug the script?

Another thing i was wondering is for the lines that calculate each amount etc - could you add comments as to what each line does ,,, im still trying to learn basic scripting and some of the things such as:

echo "scale=2; $PRICE*QUANT" | bc

Any help? Thanks once again

**********EDIT************
I changed the PRICE line to this:

PRICE=`awk /^$PRODID/ products|awk -F":" '{print $3}'`

And now it gets the correct price ... before it wasnt getting anything...just a blank...because the field seperator of file 'products' is a command (,) and there is only 3 fields, PROD-ID, NAME, PRICE

Now (with your awesome help) we have got it working in terms of each associate and their sales per product - i now should just need to add an array maybe for total[ASSOCIATE-ID]=total[ASSOCIATE-ID]+$price

Would this work? Ill try it and let you know --- lol.

Thanks folks!

Well, in basic bash scripting you cannot add floating point numbers, and i assume your price is floating point.

So in order to add those numbers you need the bc command to do this, hence the command

TOTAL=$(echo "scale=2; $PRICE*$QUANT" | bc)

do a man bc on your system and it'll give you all the details. The scale=n, means n places after the decimal.

The best way to debug it, for me atleast is run it through one loop at a time with print statements, so that you can see what values are being assigned to your variables and what is being computed.

You should be able to use an array to add up the prices for each associate.

After playing around with my script some i have come up with something like this:
( I am having problem in figuring out where i want to be printing the names ... under which loop - also can i use an array to store the GRANDTOTALS for each associate? --- if so i could then do a basic loop at the bottom of the main script that will print out the results as i want them:

NAME POSITION SALES
John Doe Clerk 284.74
George Bush President 1059.67
... ... ..........

If i were able to get my names and positions and total sales into arrays, i could use a simple loop like:

while ["$ID -le 6 ]
   do
   echo "${NAMES[$ID]}          ${POSITION[$ID]}          ${TOTALSALES[$ID]}"
   ID=$ID+1
   done

Would something like this be possible - and how could i get this working under my current script/code as i am unsure where to write assignment statements into the arrays as the 2 looping statements in the main block of script is confusing to me.

Here my current script (NOTE: I have part of commented out lines of code etc all over because im trying to figure out where to play assignment statements for my array(names) and how best to print out the information.

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales
#cat /tmp/newSales

ID=1
NAMES=()
while [ $ID -le 6 ]
do
  awk /[2][$ID]$/ /tmp/newSales > /tmp/sales.2$ID
  let ID=$ID+1
done
GRANDTOTAL=0
ID=1
while [ $ID -le 6 ]
do
  echo "SALES FOR ASSOCIATE 2$ID"
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QUANT=`echo $line|cut -d"," -f2`
    PRICE=`awk /^$PRODID/ products|awk -F":" '{print $3}'`
    TOTAL=$(echo "scale=2; $PRICE*$QUANT" | bc)
    GRANDTOTAL=$(echo "scale=2; $GRANDTOTAL+$TOTAL" | bc)
done < "/tmp/sales.2$ID"

  NAMES[$ID]=`awk -F"/" '{print $2}' associates`
 # echo "NAME[$ID]: ${NAMES[$ID]}"
 # echo Grand total for 2$ID: $GRANDTOTAL

  GRANDTOTAL=0
let ID=$ID+1
done

echo "NAME[$ID]: ${NAMES[$ID]}" #this is just an attempt to print the names one at a time

ID=1
while ["$ID" -le 6]
  do
    echo "2$ID     ${NAMES[$ID]}    TOTAL (LATER )" 
    ((ID+=1))
  done
# removes all created files
rm /tmp/sales.2*

/home/lx/z109079 : ./newtest.sh
SALES FOR ASSOCIATE 21
SALES FOR ASSOCIATE 22
SALES FOR ASSOCIATE 23
SALES FOR ASSOCIATE 24
SALES FOR ASSOCIATE 25
SALES FOR ASSOCIATE 26
NAME[1]: John Doe
George Bush
Susan Worker
Fast Buck
Hillary Clinton
Dennis Miller

Thanks once again for any help. Always much appreciated...more than u can know

You have the correct idea, but a couple of things.

1. When you extract the name from the associates file you also need to use the ID as a pattern to get the correct name.

2. You can declare the arrays to store your total sales and your names as follows

declare -a totalsales
declare -a names

and then assign the values to them in the main loop, once for each ID. You could have a separate loop to print them out or you could just print them in the main while loop, before you increment ID. Its upto you.

totalsales[$ID]=$GRANDTOTAL

1. When you extract the name from the associates file you also need to use the ID as a pattern to get the correct name.

Does this mean something like:

NAMES[$ID]=`awk -F"/" '/^2$ID/ {print $2}' associates`

If so - this doesnt work for me at all - i just get blank line if i try doing something like:

echo "NAME[$ID]: ${NAMES[$ID]}"

2. You can declare the arrays to store your total sales and your names as follows

declare -a totalsales
declare -a names

Where would i declare these at the top of my program like?:

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales

[B]declare -a totalsales
declare -a names[/B]
ID=1
NAMES=()
while [ $ID -le 6 ]
do

Using declare -a names
does not help me in getting output for a persons name into my array - any ideas?

totalsales[$ID]=$GRANDTOTAL

With the above code - i think this is the wrong way round - i want to store the associates (all 6 of them) into an array just like i would for names...so....
TOTALSALES[1]=X for sales for John Doe
TOTALSALES[2]=Y for sales for President Bush
etc
etc

Make sense - but as i said - lets deal with the names - then once i get that - i should be able to get the total sales and position arrays sorted. Thanks

*****************EDIT*******************
If i edit my line to this:

while [ $ID -le 2 ]
do
  echo "SALES FOR ASSOCIATE 2$ID"
  NAMES[$ID]=`awk -F"/" '[B]/^21/[/B] {print $2}' associates`
  echo "Name: ${NAMES[$ID]}"
  while read line
  do

I get this:


/home/lx/z109079 : ./newtest.sh
SALES FOR ASSOCIATE 21
Name: John Doe
Grand total for 21: 284.74

I just cant get it working through the entire array ----

I usually declare the arrays at the top of the script.

Something like this perhaps ? It uses 2 arrays one to store the names and the other to store the sales values.

I am not sure why your awk line doesn't work, since it works off the command prompt. For some reason you need to split it up in your script as below. I'll need to research that some more.

declare -a totalsales
declare -a names

-
-
-
-

while [ $ID -le 6 ]
do
  GRANDTOTAL=0
  echo "SALES FOR ASSOCIATE 2$ID"
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QUANT=`echo $line|cut -d"," -f2`
    PRICE=`awk /$PRODID/ products|awk -F"." '{print $3"."$4}'`
    TOTAL=$(echo "scale=2; $PRICE*$QUANT" | bc)
    GRANDTOTAL=$(echo "scale=2; $TOTAL+$GRANDTOTAL" | bc)
  done < "/tmp/sales.2$ID"

  totalsales[$ID]=$GRANDTOTAL
  names[$ID]=`awk /^[2]$ID/ associates|awk -F"/" '{print $2}'`
  echo "Associate 2$ID  ${names[$ID]} made ${totalsales[$ID]}"
  let ID=$ID+1
done
#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales
#cat /tmp/newSales
declare -a names
declare -a totalsales
declare -a position
ID=1
while [ $ID -le 6 ]
do
  awk /[2][$ID]$/ /tmp/newSales > /tmp/sales.2$ID
  let ID=$ID+1
done

GRANDTOTAL=0
ID=1
while [ $ID -le 6 ]
do
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QUANT=`echo $line|cut -d"," -f2`
    PRICE=`awk /^$PRODID/ products|awk -F":" '{print $3}'`
    TOTAL=$(echo "scale=2; $PRICE*$QUANT" | bc)
    GRANDTOTAL=$(echo "scale=2; $GRANDTOTAL+$TOTAL" | bc)
done < "/tmp/sales.2$ID"

totalsales[$ID]=$GRANDTOTAL
NAMES[$ID]=`awk /^[2]"$ID"/ associates | awk -F"/" '{print $2}'`
[B]position[$ID]=`awk /[a-z]$/ associates | awk -F"/" '{print $4}'`[/B]

#Prints all the lines as NAME  POSITION  TOTALSALES
echo "${NAMES[$ID]} ${position[$ID]} ${totalsales[$ID]}"

GRANDTOTAL=0
let ID=$ID+1
done

# removes all created files
rm /tmp/sales.2*
rm /tmp/newSales

My problem now is with the highlighted code... if i comment out that line i get this as a result:
/home/lx/z109079 : ./newtest.sh
John Doe 284.74
George Bush 1059.67
Susan Worker 279.52
Fast Buck 2504.83
Hillary Clinton 151.00
Dennis Miller 1.98
(remember that is with the BOLD line in the script above (#) commented out.)

If i include the line i get this:

/home/lx/z109079 : ./newtest.sh
John Doe Clerk
President
Manager
Stock Boy
Candidate
Commedian 284.74
George Bush Clerk
President
Manager
Stock Boy
Candidate
Commedian 1059.67
....and so on through 6th person

So its a similar problem as my name array - but im using a similar line of awk for it ... im just unsure how to apply the /********/ part of the first awk section...am i doing this wrong?

Thanks folks ever so much AGAIN!!!

Position works the same way as name does. You need to get the final field which is the position for that particular id, and not for a character string at the end of the line. That'll get you all the positions.

Using the bold part below i want to get something that looks like this:

Marine Parts R Us
Main catalog
name position total sales
======================================
John Doe clerk 10,000
George Bush president 97.95
.....

So the total sales part needs to be sorted by price...this is surely possible with what i have below:

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales
#cat /tmp/newSales
declare -a names
declare -a totalsales
declare -a position
echo -e "Name:\tPosition:\tTotal Sales:"
ID=1
while [ $ID -le 6 ]
do
  awk /[2][$ID]$/ /tmp/newSales > /tmp/sales.2$ID
  let ID=$ID+1
done

GRANDTOTAL=0
ID=1
while [ $ID -le 6 ]
do
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QUANT=`echo $line|cut -d"," -f2`
    PRICE=`awk /^$PRODID/ products|awk -F":" '{print $3}'`

    TOTAL=$(echo "scale=2; $PRICE*$QUANT" | bc)
    GRANDTOTAL=$(echo "scale=2; $GRANDTOTAL+$TOTAL" | bc)
done < "/tmp/sales.2$ID"

totalsales[$ID]=$GRANDTOTAL
NAMES[$ID]=`awk /^[2]"$ID"/ associates | awk -F"/" '{print $2}'`
position[$ID]=`awk /^[2]"$ID"/ associates | awk -F"/" '{print $4}'`

#echo -e "Name:\tPosition:\nTotal Sales:"
echo ${NAMES[$ID]}":"${position[$ID]}":"${totalsales[$ID]} >> [B]/tmp/output.$$[/B]

GRANDTOTAL=0
let ID=$ID+1
done

[B]cat > /tmp/output.$$ << DONE
BEGIN {
        FS=":"
        print "Marine Parts R Us"
        print "Main Catalog"
        print "Name\t\tPosition:\t\t\tTotal Sales:"
        print "======================================"
}
{
        printf("%3d\t%-20s\t%6.2f\n", \$1, \$2, \$3)
}
END {
        print "======================================"
}
DONE
sort /tmp/output.$$ | awk -f /tmp/output.$$
/bin/rm -f /tmp/output.$$[/B]

#GRANDTOTAL=0
#let ID=$ID+1
#done

#echo CAT OUTPUT
#cat /tmp/output.$$

# removes all created files
rm /tmp/sales.2*
rm /tmp/newSales
#rm /tmp/output.$$

echo ${NAMES[$ID]}":"${position[$ID]}":"${totalsales[$ID]} >> /tmp/output.$$
This line creates this file:

John Doe:Clerk:284.74
George Bush:President:1059.67
Susan Worker:Manager:279.52
Fast Buck:Stock Boy:2504.83
Hillary Clinton:Candidate:151.00
Dennis Miller:Commedian:1.98

Which i want the bolded code to sort but ... its not getting the right file - nor is it able to sort it correctly... any ideas?

You could make this much easier :)

Once you have your output file with the values, all you really need to do is cat the output and pipe it into the sort. <Check the man pages for the sort and it'll tell you how to sort a delimited file with a certain key>, and then pipe the sort results into an awk statement to give you the formatted output.

I am trying something like what you said - but could you please give me more information about the use of the pipe (|). What command (ie the first or 2nd?) gets put into the input of what command (the 1st or 2nd)...i know its basic stuff - but looking online at examples its not opbvious.

This is what i have tried so far... any hints? If you answer the above and help me figure out the options for the sort/awk it would be awesome.

sort -n /tmp/output.$$ | awk -F":" '{print $1 $2 $3}'

Gives me this:

/home/lx/z109079 : ./newtest.sh
Name: Position: Total Sales:
Dennis MillerCommedian1.98
Fast BuckStock Boy2504.83
George BushPresident1059.67
Hillary ClintonCandidate151.00
John DoeClerk284.74
Susan WorkerManager279.52

script:

#! /bin/bash
awk '/2007/ {print $0}' sales > /tmp/newSales

declare -a names
declare -a totalsales
declare -a position

echo -e "Name:\tPosition:\tTotal Sales:"
ID=1
while [ $ID -le 6 ]
do
  awk /[2][$ID]$/ /tmp/newSales > /tmp/sales.2$ID
  let ID=$ID+1
done

GRANDTOTAL=0
ID=1
while [ $ID -le 6 ]
do
  while read line
  do
    PRODID=`echo $line|cut -d"," -f1`
    QUANT=`echo $line|cut -d"," -f2`
    PRICE=`awk /^$PRODID/ products|awk -F":" '{print $3}'`
    TOTAL=$(echo "scale=2; $PRICE*$QUANT" | bc)
    GRANDTOTAL=$(echo "scale=2; $GRANDTOTAL+$TOTAL" | bc)
done < "/tmp/sales.2$ID"

totalsales[$ID]=$GRANDTOTAL
NAMES[$ID]=`awk /^[2]"$ID"/ associates | awk -F"/" '{print $2}'`
position[$ID]=`awk /^[2]"$ID"/ associates | awk -F"/" '{print $4}'`

echo ${NAMES[$ID]}":"${position[$ID]}":"${totalsales[$ID]} >> /tmp/output.$$

GRANDTOTAL=0
let ID=$ID+1
done

sort -n /tmp/output.$$ | awk -F":" '{print $1 $2 $3}' #/tmp/output.$$

# removes all created files
rm /tmp/sales.2*
rm /tmp/newSales
rm /tmp/output.$$

Im so close thanks to your help... thanks once again, so much apprecaited

Sorting a delimited file

for example if your record is and you want to sort it by the 3rd field,

a:b:c

sort -t':' -k 3

To sort it in numeric order add a -n to the line

sort -n -t':' -k 3

Your awk can just be a regular printf statement

awk -F':' '{printf("%3d\t%-20s\t$%10.2f\n", $1, $2, $3)}'

The file output.$$ is this:

John Doe:Clerk:284.74
George Bush:President:1059.67
Susan Worker:Manager:279.52
Fast Buck:Stock Boy:2504.83
Hillary Clinton:Candidate:151.00
Dennis Miller:Commedian:1.98

********EDIT********
I changed the line around and removed some parts to make it simpler (using the man page for printf()) and came up with this out put:

Dennis Miller Commedian $ 1.98
Fast Buck Stock Boy $ 2504.83
George Bush President $ 1059.67
Hillary Clinton Candidate $ 151.00
John Doe Clerk $ 284.74
Susan Worker Manager $ 279.52

From this line:

awk -F":" '{printf("%s\t%s\t$%10.2f\n", $1, $2, $3)}' /tmp/output.$$ | sort -n -t':' -k 3

Still not sorted quite right - is this something wrong with the 'sort' part of the above line?

The '|' character is a pipe. Basically what it does is send the output of one command which would otherwise go to stdout, in as the input to the next command.

The final sort and print doesn't need to be in your loop. It should be at the end of everything, because now you have your output and you're only wanting to sort and display it.

Assuming your final results are in a file called output.

cat output

displays those results , and you can use a '|' to pipe that into the sort command which is

sort -n -t':' -k 3

and then pipe the results of the sort into the awk statement for final formatting

awk -F":" '{printf("%3d\t%-20s\t%10.2f\n", $1, $2, $3)}'

The '$' signs are not needed in your printf unless you want them to appear in your output, before a certain field.

Not sure what's causing your loop, but you may want to put some print statements in there to isolate it.

Basically at the end you would have
cat output | sort ..... | awk ...

Hi

When you use internet explorer, pls pay attention to sidebar. You can see articles related, pdf or ppt file…you can find out your info.

Best regards

commented: Waste of space: 2 years late, and off-topic - go see Mr T for some pity -4
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.