Hi I have to divide two numbers in #!/bin/sh
$x = 5678
$x/1000
but calculations return only integer: 5
.
I need 5,678
.
I've tried
$x/1000.0
$x/1000.0 | bc
on first method expect integer
second method: I don't have bc
.
Hi I have to divide two numbers in #!/bin/sh
$x = 5678
$x/1000
but calculations return only integer: 5
.
I need 5,678
.
I've tried
$x/1000.0
$x/1000.0 | bc
on first method expect integer
second method: I don't have bc
.
You can use awk
:
#! /bin/sh -
x=5678 y=1000
awk -- 'BEGIN{printf "%.3f\n", ARGV[1]/ARGV[2]}' "$x" "$y"
Whether you'll get 5.678
or 5,678
will depend on the locale ($LC_ALL
, $LC_NUMERIC
, $LANG
variables) and the implementation of awk
(some of which will use .
regardless of the locale).
With the GNU implementation of awk
, you need to pass a POSIXLY_CORRECT
variable into its environment for it to honour the locale for the decimal radix character.
That also applies to input numbers:
$ LC_ALL=fr_FR.UTF-8 POSIXLY_CORRECT=1 gawk -- 'BEGIN{
printf "%.3f\n", ARGV[1]/ARGV[2]}' 1,2 10
0,120
$ LC_ALL=fr_FR.UTF-8 POSIXLY_CORRECT=1 gawk -- 'BEGIN{
printf "%.3f\n", ARGV[1]/ARGV[2]}' 1.2 10
0,100
(in that latter case, the 1.2
was interpreted as 1
, because when doing an explicit conversion of string to number (like when using the /
arithmetic operator here), awk
parses as much of the string as it can as long as it makes a valid number and ignores the rest. That .2
is not understood in that French locale as the decimal radix is ,
there, not .
).
The --
, to mark the end of options is needed in the busybox implementation of awk
which you seem to be using as it accepts options after non-option arguments, which makes it non-POSIX compliant. Without it, the above wouldn't work if $x
or $y
were negative number.
Alternatvely, you could again set $POSIXLY_CORRECT
, which would force it to parse its options the standard way. Note that in any case, busybox awk
always uses .
as the decimal radix character regardless of the locale and regardless of $POSIXLY_CORRECT
.
awk 'BEGIN{printf "%.3f\n", (-1234)/(1000)}' "$x" "$y" works ok don't using varibales
– user22090909 Aug 27 '19 at 09:19you can use the following dc
snippet to get the result:
$ dc -e "3k $x 1000/p"
echo "3k $x 1000/p" | dc
would be more portable. -e
is not a standard option. Note negative numbers have to be entered as _12345
instead of -12345
and the decimal radix is going to be .
regardless of the locale.
– Stéphane Chazelas
Aug 27 '19 at 09:09
bc
installed by default? – Kusalananda Aug 27 '19 at 09:45bc
, since last December (version 1.30.0), but it might not be compiled in, or it might be an older version. – ilkkachu Aug 27 '19 at 14:10