LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   how can I invoke "awk" from shell to do floating point math? (https://www.linuxquestions.org/questions/programming-9/how-can-i-invoke-awk-from-shell-to-do-floating-point-math-401093/)

Joseph Schiller 01-09-2006 01:41 AM

how can I invoke "awk" from shell to do floating point math?
 
hi,

How can I invoke 'awk' to do floating point math from inside shell script (like bash) and make it available for further shell processing? We want to evaluate decimal values like random() between 0 and 1 for example or do simple math operations with decimals. I don't want to invoke 'bc' or 'calc' for this purpose and I need the value inside a variable for further processig.

example:

#!/bin/bash

# easy math in bash
declare result
x=8
y=100
result=$((x*y))
echo $result # result = 800

# not easy math in bash
# bash reports an error on the decimal part
m=1.72 # generates error line 17: 1.72: syntax error in expression (error token is ".72")
n=10
result2=$((m*n))
echo $result2 # no output

# floating point math in awk?
# this part doesn't work
awk 'BEGIN { r=1.52, s=2 \
result3=$r*$s \
printf "The product is " $result3
}'

echo "Success " $result3 # value still available outside of {} scope

if [ $result3 > "3.0" ]
then
echo "We have a winner " $result3
elif "No such luck!"
fi

exit 0

paulsm4 01-09-2006 09:46 AM

Can you use the back-quote?

EXAMPLE:
Code:

% FACTOR=2.5
% RESULT=`echo $FACTOR|awk '{print 2.5 * $1}'`
% echo $RESULT
6.25


Joseph Schiller 01-09-2006 07:38 PM

Many thanks! That's really great! "Backticks" are used for command substitution that is assigning output from executed command to another command, but essentially equivalent to the form $(...). What I'd like to do, which awk does well I'm told, is to invoke awk inside bash to handle floating point math and return it to the bash for example to launch another script, pass in a variable etc. What I'd like to learn is the awk specifics that would expand the bash floating point limitations. Awk is really nifty little programming language, but most examples I find deal with text processing, selective output, columns, pattern matching, etc.

chrism01 01-09-2006 09:18 PM

This link shows the maths operators avail in awk: http://www.oracle.com/technology/pub...laney_awk.html
You will need to use backticks or $(...) to rtn the results, as you are calling another process ie awk.
Alternatively, you could try to write the whole thing in awk?
Alternatives are, as you say, using bc or calc, which require the same sort of approach, or use a lang that handles floats etc properly eg Perl.

zero79 01-10-2006 07:00 PM

you may want to try python for math operations instead of awk.

paulsm4 01-10-2006 07:23 PM

zero79 and chrism are both right:

a) awk is a great tool for, say, processing a text file a line at a time.

b) if you want elaborate processing, however, I'd urge you to look at a real programming
language (yeah, "awk" is Turing complete and all that, but...)

Python, Perl, C/C++ and Java (among many, many others) would be excellent choices.

IMHO .. PSM

Joseph Schiller 01-10-2006 10:53 PM

I appreciate python, java and other languages, and I think the point is well taken. I have a small program in java which I would like to feed data from a script, only thing that derails the process is the floating point stuff. For example, how many lines of java will require to do three simple things search, sort, and output last 10 preserving a decimal in human readable from 0.2399 to 23.99 as in the following:

#!/bin/bash
echo "Please enter symbol: "
read -e SYM
grep $sym ~/dir/file* | LC_ALL=C sort -t/ -k3n | awk -F, '{ printf("%12s\t%.2f\t%.2f\n",$1,$2*100,$3*100)}' | tail -n 10
exit 0

Let me explain what's going on here. I omit validating input, etc for simplicity and shortened the output to three fields. We are searching for a symbol like INTC, then we sort using ascii low to high using the year from the date field (3rd field seperated by forward slash) as in INTC,01/03/06,.2399,.2501, displaying the last two fields to two decimal places and the last 10 matches. Because we are using "awk" as opposed to strictly "bash" we can move the decimal point by multiplying by 100. Clearly in java I would need to write at least 50 lines of code to replace 5 or 6. What I'd like to do is take this a bit further. I'd like to assign it to a variable and if data is in a floating point, I would like to convert it before feeding it into another script. I could make the modifications easily in java, but that is too involved for other types of data.

Awk suports IEEE 754 standard for binary floating point arithmetic unlike bash. For example, I'd like to make the code like this correct: awk 'BEGIN { var=var*100 }' so that echo $var returns a value from say 0.2399 to 23.99 rather than 'var=var*100' etc. I don't have any awk reference that shows all the gory details. While it's easy to do everything else in bash, the floating is not easy. We could mimic floating point math by selecting substrings from strings and so on, but that's like spinning wheels going nowhere fast.

paulsm4 01-11-2006 11:25 PM

I'm not sure, but I get the impression that maybe you're trying to get a child process (e.g. awk) to set an environment variable in it's parent (e.g. a shell)? If so ... you can't. Environment variables can be copied from parents to children, but a child cannot make any changes to its parent's environment. If that's what you were thinking of...

bigearsbilly 01-12-2006 05:00 AM

forgive me, but shell doesn't do maths well, and your program
does lots of maths. Instead of trying to mangle it maybe use a more suitable
tool!
(call me old-fashioned) ;)


All times are GMT -5. The time now is 12:09 AM.