LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Bash script formatting problem (https://www.linuxquestions.org/questions/linux-newbie-8/bash-script-formatting-problem-835684/)

New2LinuxMN 10-01-2010 02:13 PM

Bash script formatting problem
 
I've created a simple loan script and I am trying to display a list of information on the screen: PaymentNumber, Interest, MonthlyPayment and Balance. When I'm calculating some of these values the decimals number exceed 2 digits past the decimal point. How can I go about formatting so it doesn't happen? I also want everything to be displaybed right justified.

Here is some of my code:
READ PRICE
READ YRLY_INTEREST
READ MONTHLY_PYMT

MONTHLY_INTEREST=$(echo "scale=3; $YRLY_INTEREST / 12"|bc)
PAYMENT_NO=0
BALANCE=$PRICE

while [ `echo $BALANCE | cut -d. -f1` -gt 0 ]
do
PAYMENT_NO=`expr $PAYMENT_NO + 1`
INTEREST=$(echo "scale=3; $MONTHLY_INTEREST / 100* $BALANCE"|bc)
BALANCE=$(echo "scale=2; $BALANCE + INTEREST - $MONTHLY_PYMT"|bc)

if [ `echo $BALANCE | cut -d. -f1` -lt 0 ]
then
MONTHLY_PYMT=$(echo "scale=2; $MONTHLY_PYMT + $BALANCE"|bc)
BALANCE=0
fi

printf "%9s %9s %9s %9s\n" $PAYMENT_NO $INTEREST $MONTHLY_PYMT $BALANCE
done

I've tried other things arguments in the printf statement but won't give me the results wanted.

I want everything right justified and if a number is a decimal i want it to be two places past the decimal point. Thanks!

GrapefruiTgirl 10-01-2010 02:46 PM

bash printf formatting, string number conversion
 
There were a few more little things amiss in the code; you'll have to look carefully at this to see what's changed. It works, but there are better ways of doing some things in here - I've left it mostly as it was to make it (hopefully) easier to spot the differences..
Code:

#!/bin/bash

read PRICE
read YRLY_INTEREST
read MONTHLY_PYMT

MONTHLY_INTEREST=$(echo "scale=3; $YRLY_INTEREST / 12"|bc); PAYMENT_NO=0; BALANCE=$PRICE
while [ $(( $(echo $BALANCE | cut -d. -f1) )) -gt 0 ]; do
    PAYMENT_NO=`expr $PAYMENT_NO + 1`; INTEREST=$(echo "scale=3; $MONTHLY_INTEREST * $BALANCE / 100"|bc)
    BALANCE=$(echo "scale=2; $BALANCE + $INTEREST - $MONTHLY_PYMT"|bc);
    if [ $(( $(echo $BALANCE | cut -d. -f1) )) -lt 0 ]; then
        MONTHLY_PYMT=$(echo "scale=2; $MONTHLY_PYMT + $BALANCE"|bc)
        BALANCE=0
    fi
    printf "%s %9.2f %9.2f %9.2f\n" $PAYMENT_NO $MONTHLY_INTEREST $MONTHLY_PYMT $BALANCE;
done

# OUTPUT:
Code:

499
13
46
1      1.08    46.00    458.40
2      1.08    46.00    417.37
3      1.08    46.00    375.89
4      1.08    46.00    333.96
5      1.08    46.00    291.57
6      1.08    46.00    248.73
7      1.08    46.00    205.42
8      1.08    46.00    161.65
9      1.08    46.00    117.40
10      1.08    46.00    72.67
11      1.08    46.00    27.46
12      1.08    27.75      0.00
sasha@reactor:


martinbc 10-01-2010 03:35 PM

Not all functions
 
Hi New2LinuxMN

I've never used bc before so it's been nice to play with it.
Reading the manual it says that not all functions take any notice of scale.
Compare the output of
Quote:

echo "scale=2; (1000.456 + 23.654) / 1"|bc
Quote:

1024.11
with
Quote:

echo "scale=2; (1000.456 + 23.654) "|bc
Quote:

1024.110
Martin

ghostdog74 10-01-2010 07:27 PM

I suggest you use awk (or a language such as Python) to do this
Code:

awk 'BEGIN{
  printf "Enter price: "
  getline PRICE<"-"
  printf "Enter yearly interest: "
  getline YRLY_INTEREST <"-"
  printf "Enter monthly payment: "
  getline MONTHLY_PYMT <"-"
  MONTHLY_INTEREST=sprintf("%.3f",YRLY_INTEREST / 12)
  PAYMENT_NO=0
  BALANCE=PRICE
  while ( int(BALANCE) > 0 ) {
    PAYMENT_NO+=1
    INTEREST=sprintf("%.3f",MONTHLY_INTEREST / 100 * BALANCE)
    BALANCE=sprintf("%.2f", BALANCE + INTEREST - MONTHLY_PYMT)
    if ( int(BALANCE) < 0 ) {
        MONTHLY_PYMT=sprintf("%.2f",MONTHLY_PYMT + BALANCE)
        BALANCE=0
        break
    }
    printf "%9s %9s %9s %9s\n", PAYMENT_NO ,INTEREST ,MONTHLY_PYMT ,BALANCE
  }
}'

output
Code:

# ./shell.sh
Enter price: 499
Enter yearly interest: 13
Enter monthly payment: 36
        1    5.404        36    468.40
        2    5.073        36    437.47
        3    4.738        36    406.21
        4    4.399        36    374.61
        5    4.057        36    342.67
        6    3.711        36    310.38
        7    3.361        36    277.74
        8    3.008        36    244.75
        9    2.651        36    211.40
      10    2.289        36    177.69
      11    1.924        36    143.61
      12    1.555        36    109.17
      13    1.182        36    74.35
      14    0.805        36    39.16
      15    0.424        36      3.58


New2LinuxMN 10-01-2010 11:23 PM

Well thanks everyone for your help with this.
By question for GrapefuiTgirl would be how could I get the numbers to be right justified.?

GrapefruiTgirl 10-02-2010 06:14 AM

Quote:

Originally Posted by New2LinuxMN (Post 4115351)
Well thanks everyone for your help with this.
By question for GrapefuiTgirl would be how could I get the numbers to be right justified.?

Ooops! Have a look at my printf statement near the end of the script. It is missing a "9" in the first %format- you should be able to fix it pretty easy. Look at the other examples.

Putting the "9" in the right spot produces this:
Code:

sasha@reactor: sh script
499
14
36
        1      1.17    36.00    468.82
        2      1.17    36.00    438.28
        3      1.17    36.00    407.39
        4      1.17    36.00    376.14
        5      1.17    36.00    344.53
        6      1.17    36.00    312.55
        7      1.17    36.00    280.19
        8      1.17    36.00    247.46
        9      1.17    36.00    214.34
      10      1.17    36.00    180.84
      11      1.17    36.00    146.95
      12      1.17    36.00    112.66
      13      1.17    36.00    77.97
      14      1.17    36.00    42.88
      15      1.17    36.00      7.38
      16      1.17      7.47      0.00


New2LinuxMN 10-02-2010 12:16 PM

Thank you!


All times are GMT -5. The time now is 02:03 PM.