Skip to main content

How to List Files by Size

• 2 min read
bash

Quick Answer: List Files by Size

To list files sorted by size in Bash, use ls -lhS for largest first or ls -lhr for smallest first. Use du -ah | sort -h for directory sizes. For more control, use find with sort.

Quick Comparison: File Size Sorting Methods

MethodOrderFormatBest For
ls -lhSLargest firstHuman-readableQuick view
ls -lhrSmallest firstHuman-readableQuick view
du -ahAnyDirectory sizesDisk usage
find -sizeBy criteriaFlexibleComplex filters
sort -hCustomNumericPost-processing

Bottom line: Use ls -lhS for quick listing, use find for complex filtering.


List and sort files by size in descending or ascending order. Learn using ls, du, find, and custom sorting.

List Files by Size (Descending)

# Sort files by size, largest first
ls -lhS

# Output:
# -rw-r--r--  1 user group 500M Feb 21 movie.mp4
# -rw-r--r--  1 user group 250M Feb 20 backup.zip
# -rw-r--r--  1 user group 5.2M Feb 19 document.pdf

The -h flag shows human-readable sizes, -S sorts by size.

List Files by Size (Ascending)

# Sort files by size, smallest first
ls -lhS --reverse

# Or using sort
ls -la | sort -k5 -n

Detailed Example with Filtering

# Show only files (not directories) sorted by size
ls -lahS | grep "^-"

# Show only directories sorted by size
du -sh */ | sort -hr

Using find with Sort

# Find files and sort by size (bytes)
find . -type f -printf '%s %p\n' | sort -rn | head -10

# Find and show human-readable sizes
find . -type f -exec ls -lh {} \; | sort -k5 -hr | head -10

Function to List Large Files

#!/bin/bash

list_large_files() {
  local directory="${1:-.}"
  local min_size="${2:-10M}"

  if [ ! -d "$directory" ]; then
    echo "ERROR: Directory not found: $directory"
    exit 1
  fi

  echo "=== Files larger than $min_size in $directory ==="
  echo ""

  find "$directory" -type f -size +$min_size -exec ls -lh {} \; | \
    awk '{print $5, $9}' | sort -hr
}

# Usage
list_large_files . 5M
list_large_files /var/log 1M

Output:

=== Files larger than 5M in . ===

500M /home/user/movie.mp4
250M /home/user/backup.zip
50M /home/user/archive.tar.gz

Practical Example: Disk Usage Report

#!/bin/bash

# File: disk_usage_report.sh

directory="${1:-.}"

echo "=== Disk Usage Report ==="
echo "Directory: $directory"
echo ""

# Show all files sorted by size
echo "Top 20 Largest Files:"
echo ""

find "$directory" -type f -printf '%h/%f\0' | \
  xargs -0 ls -lhS | \
  awk 'NR<=20 {printf "%10s  %s\n", $5, $9}'

echo ""
echo "Total directory size:"
du -sh "$directory"

Usage:

$ ./disk_usage_report.sh /home/user

List Subdirectories by Size

# List directories with their total size
du -sh */ | sort -hr

# In current directory
du -shc --max-depth=1 | sort -hr

# Human-readable and descending
du -sh * 2>/dev/null | sort -hr

Output:

250M  Documents
150M  Videos
85M   Pictures
32M   Downloads

Find Largest Single Files

#!/bin/bash

find_largest_files() {
  local directory="${1:-.}"
  local count="${2:-10}"

  find "$directory" -type f -printf '%s %p\n' | \
    sort -rn | \
    head -"$count" | \
    awk '{
      size=$1
      if (size > 1073741824) printf "%.2fGB  ", size/1073741824
      else if (size > 1048576) printf "%.2fMB  ", size/1048576
      else if (size > 1024) printf "%.2fKB  ", size/1024
      else printf "%dB  ", size
      print $0
    }' | \
    cut -d' ' -f1,3-
}

# Usage
find_largest_files . 10
find_largest_files /var/log 5

Sort by Size Range

#!/bin/bash

# List files within specific size range

min_size="$1"  # e.g., 1M
max_size="$2"  # e.g., 100M

find . -type f -size +$min_size -size -$max_size -exec ls -lh {} \; | \
  sort -k5 -hr | \
  awk '{print $5, $9}'

Usage:

$ ./size_range.sh 5M 100M

Size Statistics

#!/bin/bash

directory="${1:-.}"

echo "=== Size Statistics ==="
echo ""

# Largest file
largest=$(find "$directory" -type f -printf '%s\n' | sort -rn | head -1)
echo "Largest file: $(printf "%.2f" $((largest / 1048576)))MB"

# Smallest file
smallest=$(find "$directory" -type f -printf '%s\n' | sort -n | head -1)
echo "Smallest file: $smallest bytes"

# Average size
total=$(find "$directory" -type f -printf '%s\n' | awk '{sum+=$1} END {print sum}')
count=$(find "$directory" -type f | wc -l)
average=$((total / count))
echo "Average file size: $(printf "%.2f" $((average / 1024)))KB"

# Total size
echo "Total size: $(printf "%.2f" $((total / 1048576)))MB"

Human Readable Output

#!/bin/bash

bytes_to_human() {
  local bytes=$1
  if [ "$bytes" -lt 1024 ]; then
    echo "${bytes}B"
  elif [ "$bytes" -lt 1048576 ]; then
    echo "$(printf "%.2f" $((bytes * 100 / 1024)) | xargs -I {} expr {} / 100)KB"
  elif [ "$bytes" -lt 1073741824 ]; then
    echo "$(printf "%.2f" $((bytes * 100 / 1048576)) | xargs -I {} expr {} / 100)MB"
  else
    echo "$(printf "%.2f" $((bytes * 100 / 1073741824)) | xargs -I {} expr {} / 100)GB"
  fi
}

# Find and display with human sizes
find . -type f -printf '%s %p\n' | \
  while read size file; do
    echo "$(bytes_to_human $size)  $file"
  done | sort -V

Filter by Extension and Size

#!/bin/bash

# Find all .log files and sort by size

extension="$1"  # e.g., log
min_size="${2:-0}"

find . -type f -name "*.$extension" -size +$min_size -printf '%s %p\n' | \
  sort -rn | \
  head -20

Usage:

$ ./find_by_ext.sh log 1M

Monitor Growing Files

#!/bin/bash

# List files that exceed threshold

threshold="100M"
directory="${1:-.}"

find "$directory" -type f -size +$threshold -exec ls -lhS {} \; | \
  awk '{printf "%10s  %s (%s)\n", $5, $9, $6" "$7" "$8}'

Common Mistakes

  1. Not using -type f - includes directories which skews results
  2. Forgetting quotes - fails with spaces in filenames
  3. Mixing up sort order - -rn for descending, -n for ascending
  4. Using ls recursively - slow, use find instead
  5. Not handling special characters - use find’s null separator

Performance Tips

  • Use find with -printf for speed (no ls calls)
  • Use du for directory sizes
  • Use sort with numeric option (-n, -h)
  • Cache results if repeated queries
  • Avoid ls for large directories

Key Points

  • Use ls -lhS for quick file listing
  • Use find for complex filtering
  • Use du for directory sizes
  • Sort numerically with -n or -h
  • Always use -type f to filter by type

Summary

Listing files by size is essential for disk management. Use ls for quick views, find for complex filtering, and du for directory sizes. Always specify file types to get accurate results.