Sort Files and Directories by Size with du on Linux

Deepak Prasad
Tested on RHEL 10.2 (Coughlan) — vm1.lab.example
Package coreutils 9.5-8.el10_2
Applies to RHEL, Rocky Linux, AlmaLinux, Fedora, Ubuntu, Debian, and other Linux systems with GNU du
Privilege Normal user for paths you can read; sudo when directories are root-only (for example /var/log)
Scope Sort directory and file usage with du, sort, head, grep, and numeric awk filters. Uses a disposable lab tree under /tmp/du-lab. Does not replace df mount-point reporting.
Related guides df and du commands
Linux sort command
Linux file management
Find command in Linux
RHCSA tutorial

When a partition fills up, du answers which directories and files account for the space. By itself it walks the tree in discovery order; piping the output to sort puts the largest or smallest entries at the top.

The examples below use a small lab tree on vm1.lab.example at /tmp/du-lab with a 15M file, log files, and a tiny text file. Replace that path with the directory you are investigating.


Quick answer

Goal Command
Find which top-level folder uses the most space du -h --max-depth=1 /path | sort -rh | head
Find the largest files under a path du -ah /path | sort -rh | head
Find empty or nearly empty files and directories du -ah /path | sort -h | head
Find the largest .log files under a path du -ah /path | grep '\.log$' | sort -rh
List paths larger than 1 MiB du -ak /path | awk '$1 >= 1024' | sort -rn

Pipe du to sort -h so K, M, and G sizes order correctly. Add -r for largest first; omit it for smallest first.


Prepare a lab directory (optional)

Create a small tree so the sample output matches what you run:

bash
LABDIR=/tmp/du-lab
rm -rf "$LABDIR"
mkdir -p "$LABDIR"/{logs,archive,small}
dd if=/dev/zero of="$LABDIR/archive/big.bin" bs=1M count=15 status=none
dd if=/dev/zero of="$LABDIR/logs/app.log" bs=1M count=3 status=none
dd if=/dev/zero of="$LABDIR/logs/rotated.log.1" bs=512K count=1 status=none
dd if=/dev/zero of="$LABDIR/small/note.txt" bs=1K count=10 status=none
printf "x" > "$LABDIR/small/tiny.log"

The fixture finishes silently when dd succeeds. Use du -sh "$LABDIR" afterward if you want a one-line total before sorting. Remove the tree with rm -rf /tmp/du-lab when you are done.


Sort largest subdirectories

To rank immediate children without listing every nested file, cap depth at one and sort descending:

bash
du -h --max-depth=1 /tmp/du-lab | sort -rh | head

Sample output:

output
19M	/tmp/du-lab
15M	/tmp/du-lab/archive
3.5M	/tmp/du-lab/logs
16K	/tmp/du-lab/small

The first line is the whole tree total; the lines below are each subdirectory's aggregate. That is usually the fastest first pass on a full disk — see which top-level folder dominates before you drill deeper.


Sort largest files and directories

Add -a when you need individual files, not just folder totals:

bash
du -ah /tmp/du-lab | sort -rh | head

Sample output:

output
19M	/tmp/du-lab
15M	/tmp/du-lab/archive/big.bin
15M	/tmp/du-lab/archive
3.5M	/tmp/du-lab/logs
3.0M	/tmp/du-lab/logs/app.log
512K	/tmp/du-lab/logs/rotated.log.1

Directory lines still appear because du prints totals for each directory it visits. The single 15M file stands out clearly in the sorted list.


Sort smallest files and directories

Omit -r on sort to list smallest entries first:

bash
du -ah /tmp/du-lab | sort -h | head

Sample output:

output
4.0K	/tmp/du-lab/small/tiny.log
12K	/tmp/du-lab/small/note.txt
16K	/tmp/du-lab/small
512K	/tmp/du-lab/logs/rotated.log.1
3.0M	/tmp/du-lab/logs/app.log

That pattern helps surface entries using the least disk space, including small files and directories.


Limit how deep du walks

--max-depth=1 on a production path such as /var keeps the listing readable:

bash
du -h --max-depth=1 /var | sort -rh | head

Run that with sudo if your user cannot read every subdirectory. Increase the depth when one subdirectory is large but you still need more detail:

bash
du -h --max-depth=2 /tmp/du-lab | sort -rh | head

Pair depth limits with df and du when you need mount-point totals versus directory breakdowns on the same host.


Filter by file extension

grep after du keeps only paths whose names match a pattern:

bash
du -ah /tmp/du-lab | grep '\.log$' | sort -rh

Sample output:

output
3.0M	/tmp/du-lab/logs/app.log
4.0K	/tmp/du-lab/small/tiny.log

Anchor the pattern with $ so rotated.log.1 does not match when you only want paths that end in .log. For complex rules, find with -size may fit better than chaining many grep stages.


Filter by size threshold with numeric du

Filtering the human-readable du -h column in awk breaks when sizes use mixed suffixes (512K next to 3.0M). Use du -k for numeric 1 KiB block counts. Add -a (du -ak) when individual files should also be included, then compare numbers in awk:

bash
du -ak /tmp/du-lab | awk '$1 >= 1024' | sort -rn

Sample output (paths at or above 1 MiB):

output
18960	/tmp/du-lab
15360	/tmp/du-lab/archive/big.bin
15360	/tmp/du-lab/archive
3584	/tmp/du-lab/logs
3072	/tmp/du-lab/logs/app.log

Each unit in column one is a kilobyte when you use -k. Examples for other thresholds:

Filter awk condition
Larger than 100 MiB awk '$1 >= 102400'
Between 1 MiB and 10 MiB awk '$1 >= 1024 && $1 <= 10240'
Smaller than 500 KiB awk '$1 < 500'

Append | awk '{printf "%10.1fM\t%s\n", $1/1024, $2}' only if you want megabytes in the display after numeric filtering.


Show modification time with du --time

Add --time when you want to see when large files last changed, then sort by size as usual:

bash
du -ah --time /tmp/du-lab/logs | sort -rh | head

Sample output:

output
3.5M	2026-08-21 17:15	/tmp/du-lab/logs
3.0M	2026-08-21 17:15	/tmp/du-lab/logs/app.log
512K	2026-08-21 17:15	/tmp/du-lab/logs/rotated.log.1

With --time, GNU du inserts the modification date and time between the size and path. Keep sort -rh on the size column when you are still ranking by disk usage.


Troubleshooting

Symptom Likely cause Fix
Largest folders missing from output Permission denied on subtrees Re-run with sudo du … or scan a path your user owns
sort order looks alphabetical, not by size Missing -h on human-readable input Use sort -hr or sort -rh with du -h output
awk size filter drops valid paths Filter applied to du -h suffix column Switch to du -k or du -ak and compare numeric field one
Same path appears at multiple sizes Directory totals plus -a file lines Expected with du -ah; use --max-depth=1 without -a for one line per subdirectory
Totals exceed df free space on the mount Different questions — metadata, snapshots, open deleted files Run df on the mount and read df and du commands

References


Summary

du measures disk usage under a path; sort reorders the result so the biggest or smallest entries surface first. For a quick triage pass, du -h --max-depth=1 … | sort -rh | head ranks immediate subdirectories without drowning you in every nested file.

When you need specific large files, add -a and keep sort -rh. Extension filters belong in grep; size thresholds belong in numeric du -k output parsed by awk, not in fragile regexes against 512K and 3.0M strings in the same column.

After you identify the heavy paths, decide whether to archive, truncate, or delete — and use df on the mount point to confirm how much space you need back. For mount-level reporting and du depth flags in one place, keep df and du commands nearby when a filesystem alarm fires.


Frequently Asked Questions

1. Why pipe du to sort instead of using du alone?

du prints paths in walk order, not by size. sort -h or sort -rh orders the size column so head can show the largest or smallest entries first.

2. What is the difference between du -h and du -ah?

Without -a, du reports directory totals only. With -a, every file is listed too, which you need when hunting a few large files inside otherwise small folders.

3. Why do awk filters on du -h output fail for some sizes?

Human-readable suffixes like 1.5M mix letters and numbers. Use du -k for numeric 1 KiB block counts, add -a when you need individual files too, filter with awk on column one, then add -h only if you want readable output afterward.

4. Can du show sizes for only one directory level?

Yes. du -h --max-depth=1 sums each immediate subdirectory without listing every nested file. Add -a only when you also want file-level lines at that depth.

5. How does du relate to df when a disk looks full?

df reports free space on mounted file systems. du walks a directory tree to explain what consumes space under a path. They answer different questions; see the df and du cheat sheet for pairing them.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration