1. Overview
Determining the minimum or maximum between two numbers is a common and seemingly straightforward task. However, Unix-like operating systems surprisingly lack a built-in command dedicated to this operation.
In this tutorial, we’ll see some command-line techniques as well as learn about creating scripts to perform the task of finding the larger or smaller of two numbers.
2. The Ternary Operator
Let’s start with the shell arithmetic expansion and the ternary operator to perform the task at hand.
The ternary operator is a concise way of expressing if–else statements and has a basic syntax:
condition ? expression_if_true : expression_if_false
When it comes to numerical expressions, in place of condition, we can check if one number is greater or smaller than the other like a > b, a < b, and similar. If true, we output a; otherwise, we output b.
To implement this in the shell, we use the $(( … )) arithmetic expansion construct to evaluate the arithmetic expression written inside the parentheses:
$(( a > b ? a : b )) # maximum
$(( a < b ? a : b )) # minimum
Let’s see a complete example:
$ a=10; b=8
$ echo $(( a > b ? a : b ))
10
Since the value of a is 10, it’s the larger number and is therefore the output. Notably, if the numbers are equal, we return b.
3. Sorting and head or tail
Another approach involves combining two command-line utilities: sort along with either head or tail. This approach is versatile and can be extended to identify the minimum or maximum within a set of numbers, not just limited to two.
To implement this, we utilize the sort command with the -n option for numerical sorting. The default order is ascending. To apply the sort command to an array, we format it with newline separation using the printf command. Piping this formatted output to sort organizes the list effectively.
$ printf "%d\n" "${numbers[@]}" | sort -n
8
10
In this case, ${numbers[@]} expands to all elements of the array.
To find the largest number, we could further pipe the previous command into tail:
$ printf "%d\n" "${numbers[@]}" | sort -n | tail -1 # maximum
10
Similarly, to determine the smallest number, we employ the head command with the -1 flag to extract the first line of the output:
$ printf "%d\n" "${numbers[@]}" | sort -n | head -1 # minimum
8
Adding any syntactically correct number to the array would preserve the functionality, so we can find the largest or smallest element of the whole array.
4. test and Expressions
The next command we’ll look into is test, a versatile utility for file type checks and value comparisons.
In particular, we focus on the -gt (greater than) and -lt (less than) flags:
$ test "$a" -gt "$b" && echo $a || echo $b # maximum
$ test "$a" -lt "$b" && echo $a || echo $b # minimum
We start by comparing the numeric values of two variables, a and b, using either the test command or the syntax [ “$a” -gt “$b” ]. This comparison checks if the value of a is greater than b. Swapping -gt with -lt would check if a is smaller than b.
Next, we employ the logical AND operator (&&) to ensure that the command echo $a runs only if the previous comparison is true. If false, the command echo $b is executed.
In short, this is another shorthand if–else statement.
Let’s see a complete example of the command in action to find the bigger of two numbers:
$ a=10; b=8
$ test "$a" -gt "$b" && echo $a || echo $b
10
To find the minimum number, we could use a different representation of test:
$ [ "$a" -lt "$b" ] && echo $a || echo $b
8
In this example, first, we’re assigning values to two variables, a and b. Then, we determine the maximum value between the two. The last command showcases an alternative representation of the test command, employed to identify the smaller value.
5. Using awk
AWK is a data-driven scripting language that’s useful for manipulating data files, text retrieval, text processing, and similar tasks. Since it’s part of POSIX, the awk interpreter is a standard feature of most Unix-like operating systems.
In awk, we can use the print statement within the standard curly brackets. The print argument evaluates an expression within parentheses and provides two colon-separated alternatives after the ternary question mark operator:
echo "$a $b" | awk '{print ($1 > $2) ? $1 : $2}' # maximum
echo "$a $b" | awk '{print ($1 < $2) ? $1 : $2}' # minimum
Here, we first echo two numbers, separated by a space. Next, we pipe them into the awk tool, which runs a script to get the smaller and larger of the two respectively.
Now, let’s go through a complete example by first setting up and printing the larger number:
$ a=10; b=8
$ echo "$a $b" | awk '{print ($1 > $2) ? $1 : $2}'
10
Alternatively, we could use the syntax to print the smaller number:
$ echo "$a $b" | awk '{print ($1 < $2) ? $1 : $2}'
8
These commands work similarly to our earlier methods.
6. Scripting Solutions
As stated earlier, we could convert and run any of these commands as shell scripts.
Let’s make a Bash script that takes two numbers as command-line input and compares the numbers using the test utility as described earlier:
$ cat findMin.sh
#!/bin/bash
# Assign command line arguments to variables
a=$1 # first argument
b=$2 # second argument
# Compare the numbers and print the smaller one
[ "$a" -lt "$b" ] && echo $a || echo $b
Of course, we can rework the example for the maximum as well.
To run this file, we make it executable via the chmod command:
$ chmod +x findMin.sh
Now, we can find out the minimum of two numbers by supplying them as arguments to the script:
$ ./findMin.sh 10 8
8
As usual, if we need to carry out such operations frequently, scripts are a convenient solution.
7. Conclusion
In this article, we explored different methods using command-line utilities to find the minimum or maximum of two numbers.
In particular, we learned about various command-line utilities, such as test, awk, sort, head, tail, which we can use and combine for our purposes. Additionally, we saw how to create simple scripts to achieve the goal of finding the minimum or maximum of two numbers.