Skip to main content

How to Find Minimum Value in Bash

• 2 min read
bash math data processing min awk sort

Quick Answer: Find Minimum Value in Bash

To find the minimum value, use sort -n | head -1 for simplicity or awk for efficiency: awk '{print $1}' file | sort -n | head -1. The awk method is fastest for large datasets; sort is easiest to remember.

Quick Comparison: Find Min Methods

MethodSpeedBest ForComplexity
sort | headMediumSimple listsVery simple
awk BEGINFastestLarge filesModerate
Bash loopSlowSmall arraysSimple

Bottom line: Use sort | head -1 for quick results; use awk for large datasets.


Find the minimum value in a dataset, column, or array. This guide shows methods using sort, awk, loops, and built-in tools.

Method 1: Find Min Using sort (Simplest)

The simplest approach is to sort and take the first value:

# Sort numerically and take first
echo -e "5\n2\n9\n1\n8" | sort -n | head -1

# Output: 1

Find Min Using awk

Awk is efficient for finding minimum values:

# Simple minimum
awk 'NR==1 {min=$1} $1 < min {min=$1} END {print min}' numbers.txt

# Min in specific column
awk 'NR==1 {min=$2} $2 < min {min=$2} END {print min}' data.txt

# Min with large initial value
awk 'BEGIN {min=999999} {if ($1 < min) min=$1} END {print min}' numbers.txt

Practical Example: Find Minimum Sales

Test file (sales.txt):

John 1500
Jane 2300
Bob 950
Alice 2100
Charlie 1800
# Find lowest sales amount
awk 'NR==1 {min=$2} $2 < min {min=$2} END {print min}' sales.txt

# Find person with lowest sales
awk 'NR==1 {min=$2; person=$1} $2 < min {min=$2; person=$1} END {print person, min}' sales.txt

Output:

950
Bob 950

Find Min in Array

#!/bin/bash

# Array of values
numbers=(5 2 9 1 8 3 7)
min=${numbers[0]}

# Loop through array
for num in "${numbers[@]}"; do
  if [ "$num" -lt "$min" ]; then
    min=$num
  fi
done

echo "Minimum: $min"

Output:

Minimum: 1

Function to Find Minimum

#!/bin/bash

find_min() {
  local min=$1
  shift

  for num in "$@"; do
    if [ "$num" -lt "$min" ]; then
      min=$num
    fi
  done

  echo "$min"
}

# Usage
result=$(find_min 5 2 9 1 8)
echo "Min: $result"

Output:

Min: 1

Find Min with Multiple Conditions

#!/bin/bash

# File with values and categories
cat > products.txt << 'EOF'
apple 10 fresh
banana 15 fresh
apple 8 rotten
banana 20 fresh
cherry 5 fresh
EOF

# Find min price for "fresh" category
awk 'NR==1 && $3=="fresh" {min=$2; next} $3=="fresh" && $2 < min {min=$2} END {print min}' products.txt

# Find min and product name
awk 'NR==1 && $3=="fresh" {min=$2; item=$1; next} $3=="fresh" && $2 < min {min=$2; item=$1} END {print item, min}' products.txt

Output:

5
cherry 5

Practical Example: Smallest File Size

#!/bin/bash

# Find smallest file in directory

directory="${1:-.}"

echo "Finding smallest file in: $directory"
echo ""

smallest_file=""
smallest_size=999999999999

for file in "$directory"/*; do
  if [ -f "$file" ]; then
    size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)

    if [ "$size" -lt "$smallest_size" ]; then
      smallest_size=$size
      smallest_file=$file
    fi
  fi
done

if [ ! -z "$smallest_file" ]; then
  echo "Smallest file: $smallest_file"
  echo "Size: ${smallest_size} bytes"
else
  echo "No files found"
fi

Usage:

$ chmod +x find_smallest.sh
$ ./find_smallest.sh ~/documents
Finding smallest file in: ~/documents

Smallest file: ~/documents/readme.txt
Size: 245 bytes

Find Min with Oldest File

#!/bin/bash

# Find oldest (minimum) modification time

directory="$1"

if [ ! -d "$directory" ]; then
  echo "Usage: $0 <directory>"
  exit 1
fi

oldest_file=""
oldest_time=999999999999

for file in "$directory"/*.log; do
  if [ -f "$file" ]; then
    mod_time=$(stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null)

    if [ "$mod_time" -lt "$oldest_time" ]; then
      oldest_time=$mod_time
      oldest_file=$file
    fi
  fi
done

if [ ! -z "$oldest_file" ]; then
  echo "Oldest file: $oldest_file"
  date -d @$oldest_time
fi

Batch Processing Min Values

#!/bin/bash

# Process multiple files, finding min in each

for file in *.txt; do
  min=$(awk 'NR==1 {min=$1} $1 < min {min=$1} END {print min}' "$file")
  echo "$file: $min"
done

Find Min/Max Range

#!/bin/bash

# Find both min and max, display range

data="$1"

if [ ! -f "$data" ]; then
  echo "Usage: $0 <file>"
  exit 1
fi

awk '
NR==1 {min=$1; max=$1; next}
{
  if ($1 < min) min=$1
  if ($1 > max) max=$1
}
END {
  range = max - min
  print "Min: " min
  print "Max: " max
  print "Range: " range
}
' "$data"

Test file (values.txt):

42
17
85
23
61

Output:

Min: 17
Max: 85
Range: 68

Find Min with Error Handling

#!/bin/bash

find_min_safe() {
  local file="$1"

  if [ ! -f "$file" ]; then
    echo "ERROR: File not found: $file"
    return 1
  fi

  local min=$(awk '
    NR==1 {
      if ($1 ~ /^-?[0-9]+\.?[0-9]*$/) {
        min=$1
      }
      next
    }
    {
      if ($1 ~ /^-?[0-9]+\.?[0-9]*$/ && $1 < min) {
        min=$1
      }
    }
    END {print min}
  ' "$file")

  if [ -z "$min" ]; then
    echo "ERROR: No valid numbers found"
    return 1
  fi

  echo "$min"
}

result=$(find_min_safe "numbers.txt")
echo "Minimum: $result"

Using sort for Min Value

# For floating point numbers
awk '{print $1}' values.txt | sort -n | head -1

# Ascending order (min at start)
sort -n numbers.txt | head -1

# Descending order
sort -rn numbers.txt | tail -1

Compare Min and Max Together

#!/bin/bash

file="$1"

awk '
NR==1 {min=$1; max=$1; next}
{
  if ($1 < min) min=$1
  if ($1 > max) max=$1
}
END {
  printf "Min: %d, Max: %d, Avg: %.2f\n", min, max, (min+max)/2
}
' "$file"

Performance Tips

For large files with many values:

# Fastest: single awk pass
time awk 'NR==1 {min=$1} $1 < min {min=$1} END {print min}' huge_file.txt

# Moderate: sort
time sort -n huge_file.txt | head -1

# Slowest: bash loop
time while read num; do ... done < huge_file.txt

Awk is typically fastest for finding minimum in large datasets.

Common Mistakes

  1. Not initializing min properly - use first line or large initial value
  2. Using wrong comparison operator - use -lt not < in bash
  3. Missing END block - must print min after loop completes
  4. Floating point precision - awk handles this better than bash
  5. Skipping validation - check data type is numeric

Key Points

  • Use awk for efficient processing
  • Use sort | head -1 for simple cases
  • Initialize min to first value to avoid issues
  • Use -lt for integer comparison in bash
  • Test with negative numbers and edge cases

Summary

Finding minimum values is essential for data analysis. Use awk for efficiency, sort for simplicity, and bash loops for small datasets. Always properly initialize and validate your data.