1. Overview
There are several commands and utilities in Bash for performing division. In addition to them, we can also use the scripting languages available in Linux distributions.
In this tutorial, we will go over the following options for division in Bash:
- The expr, let, and printf commands
- The double parentheses compound command
- The bc and awk utilities
- The Python and Perl programming languages
We will use the division operator, namely /, in all of these options.
2. Using the expr Command
One command that we can use for the division is the expr command:
$ x=60
$ y=-3
$ expr $x / $y
-20
It returns an integer even if the result should actually be a floating-point number:
$ x=60
$ y=-9
$ expr $x / $y
-6
Here, we expect the result to be approximately -6.67, but the decimal point and the digits after the decimal point were truncated. This is because Bash doesn’t support floating-point arithmetic.
Furthermore, the expr command cannot take a floating-point number as input either:
$ x=60.0
$ y=-3
$ expr $x / $y
expr: non-integer argument
The spaces before and after the division operator are important:
$ x=60
$ y=-3
$ expr $x/$y
60/-3
As we see, if there are no spaces before and after the division operator, the expression supplied to the expr command is evaluated as a string. We get a syntax error if we omit the spaces either before or after the division operator:
$ expr $x /$y # No space after /
expr: syntax error: unexpected argument '/-3'
$ expr $x/ $y # No space before /
expr: syntax error: unexpected argument '-3'
3. Using the let Command
We may also use the let command for division. It takes one or more arithmetic operations and evaluates them.
Let’s do the division with the let command:
$ let x=60 y=-9 result=x/y
$ echo $result
-6
We can do the same division by using shell variables not defined within the context of the let command:
$ x=60
$ y=-9
$ let result=$x/$y
$ echo $result
-6
Similar to the expr command, the result of the division is an integer. Also, the numerator and the denominator must be integers, they can’t be floating-point numbers:
$ x=10.5
$ y=-2
$ let result=$x/$y
-bash: let: result=10.5/-2: syntax error: invalid arithmetic operator (error token is ".5/-2")
4. Using the Double Parentheses Compound Command
Another way of performing division is using the double parentheses compound command, $((…)):
$ x=60
$ y=-9
$ echo $(($x / $y))
-6
The limitations about the presence of the spaces before and after the division operator for the expr command aren’t valid for the double parentheses compound command:
$ x=60
$ y=-9
$ echo $(($x/$y)) # No spaces before and after /
-6
We can see that the result is an integer like the outputs of the expr and let commands. Therefore, the numerator and the denominator must also be integers, they can’t be floating-point numbers:
$ x=10.5
$ y=-2
$ echo $(($x/$y))
-bash: 10.5/-2: syntax error: invalid arithmetic operator (error token is ".5/-2")
5. Using the printf Command
Another command that we can use for the division is the printf command. This command is similar to its counterpart in the C programming language.
It takes a format specification and arguments as the inputs and prints a formatted text as the output:
$ x=60
$ y=-9
$ printf "%f\n" $((x/y))
-6.000000
“%f\n” is the formatted text printed on the terminal. Here, %f is the format specifier. It prints the corresponding argument is a floating-point number. \n is for creating the new line. Finally, $((x/y)) is the argument supplied to the format specifier.
The decimal part of the result in the last division isn’t correct because the result of the operation $((x/y)) is -6, as we already know. The %f format specifier only printed this integer as a floating-point number, so we got -6.000000. But, obtaining a more precise result is possible:
$ printf "%f\n" $((10**6 * x/y))e-6
-6.666666
Let’s explain how we obtained this result. The argument after the format specifier, which is $((10**6 * x/y))e-6, was evaluated from left to right. First, the $((10**6 * x/y)) part of the argument was evaluated. Here, we first multiplied 10**6 (1000000) by x. Hence we got 60000000. Then, we divided it by y, so we got -6666666 due to integer division. At this point, we had -6666666e-6 as the argument passed to the format specifier. Because of e-6, the format specifier handled this number as a floating-point number and divided -6666666 by 1000000, obtaining -6.666666.
Therefore, the trick for getting a more precise result with the printf command is to use it in this general form:
$ printf "%.<precision>f\n" $((10**<precision> * <numerator>/<denominator>))e-<precision>
Here,
Let’s divide the variables using the general form above, but with a different precision:
$ printf "%.4f\n" $((10**4 * x/y))e-4
-6.6666
Since we specified 4 as the precision, -6.6666 was printed. The default precision is 6.
The numerator and the denominator must be integers, they can’t be floating-point numbers:
$ x=10.5
$ y=-2
$ printf "%f\n" $((x/y))
-bash: 10.5: syntax error: invalid arithmetic operator (error token is ".5")
6. Using the bc Command
The bc utility is also useful in performing division. bc stands for Basic Calculator. If we run the utility without any parameters, it runs in the interactive mode. In this mode, we can just type the division expression and get the result:
$ bc -q
60/-9
-6
The -q option passed to the bc command just suppresses the welcome message printed at the beginning of the interactive mode.
We cannot use the shell variables in the interactive mode. But, we can use them in the non-interactive mode using the shell pipe (|):
$ x=60
$ y=-9
$ echo "$x / $y" | bc
-6
Here, the shell pipe operator feeds the output of the echo command to the standard input of the bc command.
We can get the result as a floating-point number by using a special variable, scale, specific to the bc command. Its value is 0 by default. That is why we got no decimal points in the output of the command execution above. The scale determines the number of digits after the decimal point. If we set it to 4, we get four digits after the decimal point:
$ echo "scale=4; $x / $y" | bc
-6.6667
The numerator and the denominator can also be floating-point numbers:
$ x=10.5
$ y=-2
$ echo "scale=4; $x / $y" | bc
-5.2500
Using double quotes in the above commands is critical. Double quotes allow the shell to expand the shell variables. However, if we use single quotes instead, we’ll get a syntax error. Single quotes don’t let the shell expand the shell variables:
$ x=60
$ y=-9
$ echo '$x / $y' | bc
(standard_in) 1: illegal character: $
(standard_in) 1: illegal character: $
7. Using the awk Command
The awk command is a well-known text processing utility. It also supports performing arithmetic operations.
We can use this support together with its BEGIN rule to perform division. The awk command uses the BEGIN rule once before processing any input. So, let’s do the division using the awk command:
$ awk 'BEGIN {x=60;y=-9;print x/y}'
-6.66667
As we can see from the output, the result of the division is a floating-point number. Here, we defined the variables x and y within the actions part of the BEGIN rule. We can also use the variables already defined in the shell, but we must use double parentheses:
$ x=60
$ y=-9
$ awk "BEGIN {print $x/$y}"
-6.66667
The variables can also be floating-point numbers:
$ x=10.5
$ y=-2
$ awk "BEGIN {print $x/$y}"
-5.25
8. Using the Python Programming Language
The Python programming language usually comes installed in Linux distributions. We can execute Python statements from the command line without writing Python scripts.
Assuming that we have both Python2 and Python3 installed in our system, the python command can be a soft link to either the python2 or the python3 command. Let’s do the divisions with both of the Python versions:
$ x=60
$ y=-9
$ python3 -c "print($x/$y)"
-6.666666666666667
$ python2 -c "print($x/$y)"
-6
The –c option passed to the python2 and python3 commands let us execute Python statements from the command line.
The division of two integers in Python2 results in an integer, but it can be a floating-point number in Python3.
It’s possible to set the precision of the result in Python3:
$ python3 -c 'x=60; y=-9; print("{:.4f}".format(x/y))'
-6.6667
Python has the float data type, so the inputs of the division can be floating-point numbers:
$ python3 -c 'x=10.5; y=-2.0; print("{:.2f}".format(x/y))'
-5.25
9. Using the Perl Programming Language
Perl is also readily available in most Linux distributions. So, we can also use it for division:
$ x=60
$ y=-9
$ result=$(perl -e "print $x/$y")
$ echo $result
-6.666666666666667
The –e option passed to the perl command lets us execute Perl statements from the command line. We can set the precision of the result:
$ perl -e '$x=60; $y=-9; printf("%.4f\n", $x/$y)'
-6.6667
As Perl supports floating-point numbers, we can divide floating-point numbers:
$ x=10.5
$ y= -2
$ result=$(perl -e "print $x/$y")
$ echo $result
-5.25
10. Conclusion
In this article, we discussed several ways of performing division in Bash.
We saw that the expr, let, and double-parentheses compound commands allow only integer division, and the result is also an integer. In contrast, while the printf command also allows only integer division, the result can be a floating-point number.
Finally, we learned that it is possible to divide floating-point numbers using the bc and awk utilities and the Python and Perl programming languages.