Skip to main content

How to Get File Size

• 3 min read
bash

Quick Answer: Get File Size in Bash

To get file size in Bash, use the stat command: stat -f%z filename (macOS) or stat -c%s filename (Linux). For human-readable format, use ls -lh or du -h. The -s operator in test conditions checks if file size is greater than 0.

Quick Comparison: File Size Checking Methods

MethodOutput FormatBest ForCompatibility
stat -c%sBytesExact sizeLinux
stat -f%zBytesExact sizemacOS
ls -lhHuman-readableDisplayAll systems
du -hHuman-readableDirectory sizeAll systems
[ -s $file ]True/falseSize checkAll systems

Bottom line: Use stat for exact bytes, ls -lh for human-readable display.


Overview

Getting file size information is a common task in Bash scripting. Whether you need to monitor disk space, validate file sizes before processing, or display human-readable sizes to users, understanding different methods to retrieve file sizes is essential. This tutorial covers multiple approaches to get file sizes in both bytes and human-readable formats.

Method 1: Using stat Command

The stat command provides detailed file information including size:

# Get file size in bytes
stat --format=%s filename.txt

# Or the shorter form
stat -f %z filename.txt  # macOS

# On Linux
stat -c%s filename.txt

Example output:

$ stat --format=%s myfile.txt
1024

$ stat -c%s myfile.txt
1024

Method 2: Using wc Command

The wc command is commonly used for getting file size in bytes:

# Get file size in bytes
wc -c < filename.txt

# Get size with filename
wc -c filename.txt

Example:

$ wc -c < myfile.txt
1024

$ wc -c myfile.txt
1024 myfile.txt

Method 3: Using ls Command

The ls command shows file size in its long listing:

# Get file size from ls output
ls -l filename.txt

# Extract just the size (5th field)
ls -l filename.txt | awk '{print $5}'

# Using stat for portable across systems
ls -lh filename.txt  # Human-readable format

Example:

$ ls -l myfile.txt
-rw-r--r-- 1 user group 1024 Jan 15 10:30 myfile.txt

$ ls -l myfile.txt | awk '{print $5}'
1024

$ ls -lh myfile.txt
-rw-r--r-- 1 user group 1.0K Jan 15 10:30 myfile.txt

Method 4: Using find Command

The find command can display file sizes:

# Get size in bytes
find . -name "filename.txt" -printf '%s\n'

# Get size in human-readable format
find . -name "filename.txt" -exec ls -lh {} \;

Example:

$ find . -name "myfile.txt" -printf '%s\n'
1024

Human-Readable Format

Convert bytes to KB, MB, GB for better readability:

# Using numfmt (GNU coreutils)
numfmt --to=iec-i --suffix=B $(stat -c%s filename.txt)

# Using awk to convert bytes to human-readable
awk 'BEGIN {printf "%.2f MB\n", 1048576 / (1024*1024)}'

# Manual conversion using bc
size=$(stat -c%s filename.txt)
echo "scale=2; $size / (1024*1024)" | bc

Example:

$ numfmt --to=iec-i --suffix=B $(stat -c%s myfile.txt)
1.0KiB

$ size=$(stat -c%s myfile.txt)
$ echo "scale=2; $size / (1024*1024)" | bc
0.00

Practical Examples

Example 1: Display File Size in Both Formats

#!/bin/bash

filename="$1"

if [ ! -f "$filename" ]; then
  echo "File not found: $filename"
  exit 1
fi

# Get size in bytes
size_bytes=$(stat -c%s "$filename")

# Convert to human-readable
size_kb=$((size_bytes / 1024))
size_mb=$((size_bytes / (1024 * 1024)))

echo "File: $filename"
echo "Size in bytes: $size_bytes"
echo "Size in KB: $size_kb"
echo "Size in MB: $size_mb"

Output:

$ bash script.sh myfile.txt
File: myfile.txt
Size in bytes: 1048576
Size in KB: 1024
Size in MB: 1

Example 2: Check If File Exceeds Maximum Size

#!/bin/bash

filename="$1"
max_size=$((10 * 1024 * 1024))  # 10 MB

if [ ! -f "$filename" ]; then
  echo "File not found"
  exit 1
fi

actual_size=$(stat -c%s "$filename")

if [ "$actual_size" -gt "$max_size" ]; then
  echo "File too large: $(numfmt --to=iec-i --suffix=B $actual_size)"
  exit 1
else
  echo "File size OK: $(numfmt --to=iec-i --suffix=B $actual_size)"
fi

Output:

$ bash script.sh largefile.bin
File too large: 15.0MiB

Example 3: List Files Sorted by Size

#!/bin/bash

directory="${1:-.}"

echo "Files sorted by size (largest first):"
find "$directory" -type f -printf '%s %p\n' | \
  sort -rn | \
  while read size path; do
    human_size=$(numfmt --to=iec-i --suffix=B $size)
    printf "%10s %s\n" "$human_size" "$path"
  done

Output:

$ bash script.sh .
Files sorted by size (largest first):
      5.2M ./archive.zip
      2.1M ./video.mp4
    512.0K ./document.pdf
    256.0K ./image.jpg

Example 4: Function for Human-Readable Size

#!/bin/bash

# Function to convert bytes to human-readable format
format_size() {
  local bytes=$1
  if [ "$bytes" -lt 1024 ]; then
    echo "${bytes}B"
  elif [ "$bytes" -lt $((1024 * 1024)) ]; then
    echo "$((bytes / 1024))KB"
  elif [ "$bytes" -lt $((1024 * 1024 * 1024)) ]; then
    echo "$((bytes / (1024 * 1024)))MB"
  else
    echo "$((bytes / (1024 * 1024 * 1024)))GB"
  fi
}

# Usage
file_size=$(stat -c%s "myfile.txt")
echo "File size: $(format_size $file_size)"

Output:

$ bash script.sh
File size: 1024KB

Quick Reference - Getting File Size

CommandOutputFormat
stat -c%s file.txt1024Bytes
wc -c < file.txt1024Bytes
ls -l file.txt | awk '{print $5}'1024Bytes
ls -lh file.txt | awk '{print $5}'1.0KHuman-readable
du -h file.txt1.0KDisk usage

Performance Comparison

For checking file size:

  • stat -c%s: Fastest, most portable
  • wc -c: Fast, universal
  • ls -l: Slower, but shows more info
  • find with -printf: Good for bulk operations

Best choice: Use stat -c%s for single files, find -printf '%s' for multiple files.

Key Points

  • Use stat -c%s filename to get size in bytes
  • Use ls -lh to get human-readable sizes
  • Use numfmt for automatic unit conversion
  • Always check if file exists before getting size
  • Consider performance when processing many files
  • Account for time zone and locale in size calculations
# Get file size
file_size=$(stat -c%s "$filename")

# Check if valid
if [ "$file_size" -gt 0 ]; then
  echo "File size: $file_size bytes"
fi

# For human-readable
human_size=$(numfmt --to=iec-i --suffix=B "$file_size")
echo "Human readable: $human_size"