[tldr] Quick answer: ls alone lists names. Add -lh for readable sizes, -lt for newest first, -lS for biggest first, -v to sort version numbers correctly, --time-style=long-iso for a consistent date format, and --group-directories-first to keep folders on top. These need no extra packages — GNU coreutils ships them on Ubuntu, Debian, RHEL, Rocky and AlmaLinux. [/tldr]
[howto_callout type="tip"] Bookmark this page (🔖): you'll come back to these flags every time you log into a new server or clean up a directory full of logs and backups. Tap the bookmark button at the top right. [/howto_callout]
Why ls is enough (most of the time)
Most people stop at ls -la. Then they reach for sort, awk, stat and three pipes to answer a simple question: which file is the newest? or which one is eating my disk? GNU ls already answers both.
One check first — confirm you're on GNU coreutils:
ls --version
# ls (GNU coreutils) 9.4On Ubuntu 26.04 and later, the default may be uutils coreutils (written in Rust). Basic flags behave the same, but a few newer ones (--zero, --hyperlink) may differ, test before you rely on them in a script.
The 5 flags you should already be using
| Flag | What it does | Example |
|---|---|---|
-l | Long format: permissions, owner, size, date | ls -l |
-a | Include hidden files (.bashrc, .env) | ls -la |
-h | Human-readable sizes (K, M, G) | ls -lh |
-t | Newest modified first | ls -lt |
-S | Largest file first | ls -lS |
Combine them freely: ls -lht is "long listing, newest on top, sizes in MB", and ls -lhS | head -5 shows the five biggest items in the current directory.
1. One date format, always: --time-style
By default ls -l shows a time for recent files and a year for old ones, so two rows are rarely comparable. Fix it once:
ls -l --time-style=long-iso
# -rw-r--r-- 1 deploy deploy 2.0M 2026-11-06 14:22 backup.sqlNeed seconds and timezone? Use --time-style=full-iso. Want your own layout? --time-style=+'%d %b %Y %H:%M'.
Make it permanent so every ls -l is consistent:
echo 'export TIME_STYLE=long-iso' >> ~/.bashrc
source ~/.bashrc2. Real creation time: --time=birth
ls -l shows mtime (last content change), not creation. When you need the birth time of a file, for example to see when an unfamiliar config first appeared:
ls -l --time=birth --time-style=long-iso notes.txtIf the filesystem or kernel doesn't track birth time, ls prints a dash (-) instead of a date. that's expected, not an error.
3. Version sort: -v
Alphabetical order is wrong for versioned files: app-1.9.tar.gz sorts after app-1.10.tar.gz. Version sort fixes it:
ls -1v
# app-1.9.tar.gz
# app-1.10.tar.gz
# app-1.11.tar.gzThis is the fastest way to spot the newest release in a directory of backups.
4. Sort by what matters: --sort
ls --sort=size -lh # largest first
ls --sort=time -lh # newest first (same as -t)
ls --sort=extension # grouped by file type
ls --sort=none # no sorting at all, fastest on huge directories--sort=extension is handy when a folder mixes logs, images, SQL dumps and archives.
5. Folders above files: --group-directories-first
ls -lh --group-directories-firstDirectories appear first, then files, each group sorted alphabetically. This one flag makes project folders readable at a glance.
6. Mark every file type: -F
ls -F
# deploy.sh* docs/ logs/ backup.sql notes.txt* = executable, / = directory, @ = symlink, = = socket. You can tell what you're looking at before reading a single permission bit.
7. Comma-separated output: -m
ls -m *.conf
# nginx.conf, php.ini, redis.confUseful when you want to paste a file list into a chat, a ticket or a config line.
8. Numeric owners: -n
ls -ln
# -rw-r--r-- 1 1000 1000 6 Nov 6 14:22 notes.txtShows UID/GID instead of names, exactly what you need when files moved between servers or into a container and the ownership looks wrong.
9. Script-safe filenames: --zero
A file called my report.txt breaks any script that splits on spaces or newlines. --zero separates names with a null byte instead:
ls --zero -t -- *.txt | xargs -0 wc -cFor walking whole trees, find is still the safer tool:
find. -maxdepth 1 -type f -name '*.txt' -print0 | xargs -0 wc -cUse ls --zero when you still want ls sorting (newest first, version order) and safe filenames at the same time.
10. Speed on huge directories: -U and -f
In a cache or mail spool with hundreds of thousands of entries, sorting is what makes ls feel frozen. -U skips sorting and prints immediately; -f also disables colour and the extra stat calls.
ls -U | head
ls -fMake it daily: four aliases
export TIME_STYLE=long-iso
alias ll='ls -lh --group-directories-first'
alias lt='ls -lht'
alias lv='ls -1v'Keep aliases for interactive shells only. Scripts don't load ~/.bashrc, so a cron job that calls ll will fail with command not found on another server, write the full flags inside scripts.
The one mistake to avoid
Never parse ls output in a script to get filenames, spaces, newlines and unusual characters in filenames will silently break it. Use find... -print0 or shell globs instead, and keep ls for reading with your eyes.
FAQ
Which ls flags work on every Linux?
POSIX ls guarantees -l, -a, -t, -r, -R, -F and -i. Options like --time-style, --zero and --group-directories-first are GNU extensions, on macOS use brew install coreutils and call gls.
How do I see hidden files only?
ls -d.[!.]* lists dotfiles without . and ... Inside a normal listing, ls -A shows almost all, hidden entries included, without the two directory references.
Why does ls show a different time than the file's creation?
Because -l shows the modification time. Add --time=birth for creation time, or --time=atime / --time=ctime for access and inode-change times.
Related guides
Short, tested walkthroughs on the same topics: