Bash Modulo (Division Remainder)

Written by: Linuxopsys   |   Last updated: April 1, 2023

Many times we are only interested in what the remainder is. The mod operator finds use in generating random numbers within a specific range and formatting program output. It can even be used to generate prime numbers, check if a number is odd or even. Modulo turns up often in the majority of the numerical computations.

In this tutorial, we will learn about the modulus operations in bash.

Bash modulo

Modulo is a binary operation that evaluates the remainder when one integer is divided by another. We often abbreviate the operator as mod and represent it by the symbol %. The remainder, if integers are involved, starts from 0 and every time increments by 1, until the number becomes just one less than the number we are dividing by. This sequence keeps repeating.

Here’s the syntax:

Given two integers x and y,

x%y = r 

Where x is the dividend (numerator), y is the divisor (denominator), and r is the remainder.

How to Use Bash modulo

We will then try to find the modulus of floating point numbers. We also will understand the precedence order. After this, we are going to put everything we have learned to practice and solve some real-world problems.

1. Modulo with integer

Bash provides us with a bunch of tools to carry out the modulus operation. Some of them are expr, let, double parentheses. We can also use some powerful tools like awk, bc and printf. 

Example:

#!/bin/bash
a=12
b=7
echo $a%$b
let result=$a%$b		#Using let
echo $result

expr $a % $b			#Using expr

echo $(($a%$b))		#Using $(())

echo "$a%$b" | bc		#Using bc

awk "BEGIN {print $a%$b}"	#Using awk

printf "%i\n" $((a%b))		#Using printf

In this example we can see that, unlike other programming languages, we cannot perform the modulus operation directly. Bash will treat those variables as strings and print the result directly. As a result, we have used different command line tools to find the remainder when an integer is divided by another.

modulo with integer

2. Modulo with floating point numbers 

A floating point number is a positive or negative number with a decimal point. Most of the utilities used in the previous example cannot be used. However, we can make use of the powerful tools bash offers like bc and awk.

Example:

#!/bin/bash
a=100.0
b=21

echo "$a%$b" | bc				#Using bc

awk "BEGIN {print $a%$b}"			#Using awk

echo "100.1%21" | bc				#Using bc

awk 'BEGIN {x=100.1;y=21;print x%y}'	#Using awk

As we can see above, awk and bc are handy tools to perform the modulus. Another interesting thing that has come out is that the result of modulus may not always be an integer. 

modulo with float

3. Modulo Operator Precedences

When evaluating expressions, Bash has specific rules for the modulo operator that determine its precedence. The modulo operator (%) always shares the same order of precedence as the multiplication (*) and division (/) operators. For overriding the precedence of other operators, we can surround the operation we want to evaluate first using parentheses

Example:

#!/bin/bash
a=2
b=10
c=6
d=3

let result="$a * $b % $c + $d"
echo $result

let result="$a * $b % ($c + $d)"
echo $result

In the first case, we have both the multiplication and mod operators with the same order of precedence. Bash evaluates the expression from left to right. $a * $b is evaluated first and the result is the numerator for the modulus operation with $c. This newly generated number is then added to $d.

2* 10=20
20%6=2
2+3=5

In the second case we are making use of parentheses to give higher priority to $c +$d. Hence, this expression is calculated first and then the usual evaluation will take place.

6+3=9
2*10=20
20%9
2
Modulo Operator Precedences

Modulo in practice

Now that we have understood in detail the modulo operator, we will put it to use to tackle real-world programming problems.

Example 1: To check if number is odd or even

#!/bin/bash
echo -n "Enter a number:"
read num
if [ `expr $num % 2` == 0 ]
then
	echo "$num is even"
else
	echo "$num is odd"
fi

A number if divided by 2, leaves the remainder 1 will be odd otherwise even. In this example we evaluate the expression using the modulus operator `expr $num % 2`. If it is to 0 then it is even otherwise it is odd.

bash check if number is odd or even

Example 2: To convert hours from 24-hour format to 12-hour format

#!/bin/bash
echo -n "Enter the hour:"
read hour
if [ "$hour" -gt 24 ] || [ "$hour" -lt 0 ]
then
	echo Invalid hour entered.
	exit 1
fi
if [ "$hour" -eq 12 ]
then
	echo 12pm
elif [ "$hour" -eq 24 ]
then
	echo 0am
elif [ "$hour" -gt 12 ]
then
	echo "`expr $hour % 12` pm"
else
	echo "$hour am"
fi

In this example we are only accepting integers between 0 to 24 and discarding any other entry. If the input is between 0 to 11 we print the input directly with am. If it is 12 or 24 we print the number and accordingly add am or pm. For the remaining numbers, we evaluate the expression using the modulus operator `expr $hour % 12` and append pm.

bash convert 24-hour format to 12-hour format

Example 3: To generate a random number within a specific range

#!/bin/bash
echo $(( $RANDOM % 50 ))	#a random number between 0 to 50

This example is a simple way of generating a random number between 0 to 50. We are using the in-built $RANDOM variable to generate a random number. The generated random number is  between 0 and 32767. However, we are setting the range of the number by dividing $RANDOM with 50 and getting the remainder using $RANDOM % 50.

bash generate a random number within a specific range

Example 4: To run at specific intervals in a loop

#!/bin/bash
file=sample1.txt
lineCount=`cat $file | wc -l`
i=1
while [[ $i -ne $lineCount ]]
do
        if [ `expr $i % 3` == 0 ]
        then
                head -$i $file | tail +$i
        fi
        ((i++))
done< $file

In this example we are displaying every third line of the file. We are using the modulus operator `expr $lineCount % 3` to get every third line.

bash run at specific intervals in a loop

Conclusion

  • Bash modulo operator is used to find the remainder.
  • The modulus operation can be performed on integers as well as floating point numbers.
  • The precedence of Bash modulus is similar to multiplication and division operators.
  • We can solve real world problems by making use of the modulus operator.
SHARE

Comments

Please add comments below to provide the author your ideas, appreciation and feedback.

Leave a Reply

Leave a Comment