How to Get File Size
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
| Method | Output Format | Best For | Compatibility |
|---|---|---|---|
| stat -c%s | Bytes | Exact size | Linux |
| stat -f%z | Bytes | Exact size | macOS |
| ls -lh | Human-readable | Display | All systems |
| du -h | Human-readable | Directory size | All systems |
| [ -s $file ] | True/false | Size check | All 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
| Command | Output | Format |
|---|---|---|
stat -c%s file.txt | 1024 | Bytes |
wc -c < file.txt | 1024 | Bytes |
ls -l file.txt | awk '{print $5}' | 1024 | Bytes |
ls -lh file.txt | awk '{print $5}' | 1.0K | Human-readable |
du -h file.txt | 1.0K | Disk 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 filenameto get size in bytes - Use
ls -lhto get human-readable sizes - Use
numfmtfor 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
Recommended Pattern
# 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"