Most Linux users type ls -la dozens of times a day without exploring what the command can do. But beyond listing files, ls offers several useful options for sorting files by version, displaying file creation time, identifying file types, and producing output that is safer to use in scripts.

If you work with Linux servers, ls is probably one of the first commands you run after logging in. For most users, the command stops at ls -l or ls -la.

That is usually enough until you need to find the newest release archive in a directory full of versioned files, check when a configuration file was created, or pass filenames to a script without breaking on spaces or special characters.

The good news is that GNU ls, included in GNU coreutils, already provides options for handling these tasks. In many cases, you don’t need to combine it with sort, awk, or stat to get the information you need.

In this guide, we’ll explore 10 useful ls options that can make everyday Linux administration easier. The examples were tested with GNU coreutils 9.4 and are applicable to common Linux distributions, including Rocky Linux, AlmaLinux, RHEL, Debian, and Ubuntu.

One important exception is Ubuntu 26.04, which uses the Rust-based uutils coreutils implementation by default rather than GNU coreutils.


Although many familiar options behave similarly, some newer features may be unavailable or behave differently. We’ll highlight compatibility considerations where necessary.

Before trying the examples, check whether your system uses GNU coreutils:

ls --version

Output:

ls (GNU coreutils) 9.4
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later .
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Richard M. Stallman and David MacKenzie.

This confirms that the system uses GNU coreutils 9.4.

How ls Decides What to Show

Before exploring the 10 options, it’s worth understanding three things that control how ls displays directory contents: which timestamp it uses, how it sorts entries, and how it arranges the output. Each option covered in this guide changes one or more of these behaviors.

By default, ls sorts entries alphabetically by name. When using a long listing (-l), it displays the modification time (mtime). When writing directly to a terminal, it arranges filenames in columns.

However, when its output is redirected to a file or piped to another command, it automatically switches to one entry per line. This is why ls | wc -l can count entries correctly even when the same directory appears in multiple columns on your screen.

To demonstrate these options, we’ll use a sample project directory on our test server (192.168.122.248), logged in as the tecmint user. The directory contains several release tarballs, a database dump, a shell script, a symbolic link, and two subdirectories.

1. Show Timestamps in a Readable Format with –time-style

By default, ls -l displays timestamps differently depending on a file’s age. Recent files show the time, while older files show the year. This inconsistent format makes it harder to compare timestamps at a glance, especially when managing files across multiple releases.

The –-time-style option solves this problem by letting you choose a consistent timestamp format for every entry.

The long-iso style is particularly useful for system administrators because it displays the date and time in a predictable YYYY-MM-DD HH:MM format:

ls -l --time-style=long-iso

Output:

total 2064
-rw-r--r-- 1 tecmint tecmint       0 2026-10-27 10:25 app-1.10.tar.gz
-rw-r--r-- 1 tecmint tecmint       0 2026-10-27 10:25 app-1.9.tar.gz
-rw-r--r-- 1 tecmint tecmint 2097152 2026-10-27 10:25 backup.sql
-rwxr-xr-x 1 tecmint tecmint      10 2026-10-27 10:25 deploy.sh
drwxr-xr-x 2 tecmint tecmint    4096 2026-10-27 10:25 docs

If you need more precise information, including seconds, nanoseconds, and the time zone offset, use the full-iso style. You can also use the --full-time shortcut, which produces the same timestamp format:

ls -l --time-style=full-iso notes.txt

Output:

-rw-r--r-- 1 tecmint tecmint 6 2026-10-27 10:25:45.772729598 +0530 notes.txt

You can also define a custom timestamp format by prefixing a date-style format string with +, useful when you want timestamps to match the format used in your team’s reports or administrative scripts:

ls -l --time-style=+'%d %b %Y %H:%M' notes.txt

Output:

-rw-r--r-- 1 tecmint tecmint 6 27 Oct 2026 10:25 notes.txt

GNU ls supports several built-in timestamp styles:

  • full-iso – Displays the full date, time with nanoseconds, and time zone offset.
  • long-iso – Displays the date and time in YYYY-MM-DD HH:MM format, making it a practical choice for everyday administration.
  • iso – Displays MM-DD HH:MM for recent files and YYYY-MM-DD for older files.
  • locale – Uses your system’s locale settings to format timestamps.
  • +FORMAT – Accepts custom format specifiers, similar to the date command, such as %Y, %m, %d, %H, and %M.

If you regularly use long-iso, you don’t need to specify it every time. GNU ls reads the TIME_STYLE environment variable, so you can add the following line to your ~/.bashrc file to make it the default for your shell:

export TIME_STYLE=long-iso

After saving the file, reload your shell configuration:

source ~/.bashrc

From now on, ls -l will display timestamps using the long-iso format automatically.

2. Show File Creation Time with –time=birth

After learning how to display timestamps consistently, the next step is understanding which timestamp you’re looking at. Linux tracks several timestamps for each file, but ls -l displays the modification time (mtime) by default, which changes whenever the file’s contents are modified.

Sometimes, however, you need to know when a file was originally created on the filesystem. For example, you might want to determine when an unfamiliar configuration file first appeared on a server.

GNU ls can display a file’s birth time, also known as its creation time, using the --time=birth option:

ls -l --time=birth --time-style=long-iso notes.txt

Output:

-rw-r--r-- 1 tecmint tecmint 6 2026-10-27 10:25 notes.txt

The --time option accepts several values, allowing you to choose which timestamp appears in a long listing:

  • --time=birth (or creation) – Displays when the file was created on the filesystem.
  • --time=atime (equivalent to -u) – Displays when the file was last accessed or read.
  • --time=ctime (equivalent to -c) – Displays when the file’s metadata, such as permissions, ownership, or link count, last changed.
  • --time=mtime – Displays when the file’s contents were last modified. This is the default.

Keep in mind that birth-time availability depends on the filesystem, kernel, and system interfaces used to retrieve the timestamp. If a birth time is unavailable, GNU ls displays a placeholder rather than a valid creation date.

You can verify whether a file has a recorded birth time using stat command:

stat -c '%w' notes.txt

If the command returns a timestamp, the birth time is available. If it returns -, the system cannot provide one for that file.

One more thing to remember: copying a file with cp or extracting it from an archive creates a new filesystem object. Its birth time generally reflects when the new copy was created, not when the original file was first created.

If this helped you finally see when a file was created instead of when it was last edited, share it with someone who’s still digging through backups to answer that question.

3. Sort Release Files Correctly with -v (Version Sort)

Once you’ve learned to work with timestamps, another common problem is sorting files with version numbers in their names. By default, ls sorts filenames alphabetically, comparing characters from left to right.

This means app-1.10.tar.gz appears before app-1.9.tar.gz because the character 1 comes before 9, even though version 1.10 is newer.

The -v option, also available as --sort=version, solves this by recognizing numeric sequences within filenames and sorting them in natural version order:

ls -1 -v app-*

Output:

app-1.9.tar.gz
app-1.10.tar.gz

This is particularly useful when managing directories containing kernel images, rotated log files such as messages.1 through messages.12, or backups named with build and version numbers.

You can also combine version sorting with tail command to retrieve the highest version number, which is useful in shell scripts:

ls -1 -v app-* | tail -n 1

Output:

app-1.10.tar.gz

This approach works well when filenames follow a consistent version-numbering pattern, making it easier to identify the latest numbered release without using sort -V.

4. Sort Files by Size, Time, or Extension with –sort

Version sorting is useful for release files, but system administrators often need to answer other questions, such as which files are taking up the most space or which ones were modified most recently.

GNU ls provides the --sort option for choosing how directory entries are ordered. Many sort options also have shorter command-line equivalents.

For example, to list files and directories by size, with the largest entries first, use -S:

ls -lhS

Output:

total 2.1M
-rw-r--r-- 1 tecmint tecmint 2.0M Oct 27 10:25 backup.sql
drwxr-xr-x 2 tecmint tecmint 4.0K Oct 27 10:25 docs
drwxr-xr-x 2 tecmint tecmint 4.0K Oct 27 10:25 scripts
-rwxr-xr-x 1 tecmint tecmint   10 Oct 27 10:25 deploy.sh

Here, -h displays file sizes in a human-readable format, while -S sorts entries by size, placing the largest first.

The most useful sorting options include:

  • --sort=size (or -S) – Sorts entries by size, with the largest first. Useful for identifying large files that may be consuming disk space.
  • --sort=time (or -t) – Sorts entries by modification time, with the newest first. When combined with --time, it can also sort by the selected timestamp.
  • --sort=extension (or -X) – Groups files by their extensions, making it easier to find related file types such as .gz, .sql, and .csv. Files without extensions appear first.
  • --sort=width – Sorts entries by filename length, from shortest to longest. This can help identify unusually long filenames. This option was introduced in GNU coreutils 9.1, so it is unavailable in older versions.
  • --sort=none (or -U) – Disables sorting and displays entries in the order they are returned by the filesystem. This can improve performance when listing directories containing very large numbers of entries.

You can reverse any of these sorting orders with -r. For example, combining -t with -r lists the oldest modified files first and the newest at the bottom:

ls -ltr

This is particularly handy when checking recently updated logs, configuration files, or application releases because the newest entries appear at the end of the listing.

5. List Directories Before Files with –group-directories-first

When working in directories containing many files and subdirectories, finding a particular folder can become difficult because ls normally sorts everything together alphabetically.

The --group-directories-first option solves this by displaying directories before regular files, while preserving the selected sort order within each group.

For example:

ls -F --group-directories-first

Output:

docs/  
scripts/  
app-1.10.tar.gz  
app-1.9.tar.gz  
archive.tar.gz  
backup.sql  
data.csv  
deploy.sh*  
latest-notes@  
notes.txt  
report.pdf

This option is particularly useful when managing application directories, deployment files, and backup locations where you frequently switch between folders and files.

If you prefer this layout every time you use ls, you can create a shell alias in your ~/.bashrc file. You can also combine it with the TIME_STYLE setting from the first example:

export TIME_STYLE=long-iso
alias ll='ls -lh --group-directories-first'

After saving the file, reload your shell configuration:

source ~/.bashrc

One important limitation is that --sort=none (or -U) disables directory grouping because entries are no longer sorted into separate groups. If directory-first output matters, avoid combining these options.

6. Identify File Types with -F (–classify)

You may have noticed the /, *, and @ characters appearing after filenames in the previous output. These are file-type indicators added by the -F option, also known as --classify.

This option appends a character to each entry to identify its type, making it easier to distinguish directories, executable files, and symbolic links without using colors or a long listing.

For example:

ls -F

Output:

app-1.10.tar.gz  app-1.9.tar.gz  archive.tar.gz  backup.sql  data.csv  deploy.sh*  docs/  latest-notes@  notes.txt  report.pdf  scripts/

GNU ls uses the following indicators:

  • / – Identifies a directory.
  • * – Identifies an executable file.
  • @ – Identifies a symbolic link.
  • | – Identifies a named pipe (FIFO).
  • = – Identifies a socket.
  • > – Identifies a door, a file type used on some Unix systems such as Solaris, but not normally found on Linux.

It’s important not to confuse -F with -p. The -p option adds a trailing / only to directory names, while -F adds the appropriate indicators for several file types.

Recent GNU coreutils versions also support --classify=auto, which automatically enables classification only when output is directed to a terminal. This is useful when you want file-type indicators for interactive use without adding characters to redirected output.

For example:

ls --classify=auto

This makes ls more convenient for interactive use, although you should still avoid parsing ordinary ls output in scripts. For reliable filename handling, use find command or shell globbing instead.

If this cleared up the difference between ls -p and ls -F, share it with someone who’s still adding -l just to tell files from folders.

7. Print Filenames as a Comma-Separated List with -m

Sometimes you don’t need a traditional column or long listing. For example, you might want to copy a list of filenames into a support ticket, email, or chat message.

The -m option, equivalent to --format=commas, displays filenames separated by commas and arranges them across as few lines as possible:

ls -m

Output:

app-1.10.tar.gz, app-1.9.tar.gz, archive.tar.gz, backup.sql, data.csv,
deploy.sh, docs, latest-notes, notes.txt, report.pdf, scripts

GNU ls also supports several other output formats through the --format option:

  • --format=commas – Equivalent to -m, displaying filenames separated by commas.
  • --format=long (or verbose) – Equivalent to -l, displaying detailed file information.
  • --format=single-column – Equivalent to -1, displaying one filename per line, even when output is directed to a terminal.
  • --format=across (or horizontal) – Equivalent to -x, filling rows from left to right.
  • --format=vertical – Equivalent to -C, displaying entries in columns from top to bottom. This is the default layout when output is sent to a terminal.

These formats are useful when you want to change how filenames are presented without changing which entries are listed.

8. Control Output Width with -w (–width)

By default, ls determines the available output width from the terminal and arranges filenames accordingly. This usually works well, but the layout can change when working in narrow terminal windows, tmux panes, or remote SSH sessions.

The -w option, also available as --width, lets you specify the output width in characters. For example, setting the width to 80 characters gives ls a fixed width to work with:

ls -w 80

This is useful when you want a predictable column layout regardless of the terminal’s actual width. Setting the width to 0 removes the width limit, allowing ls to display all filenames on a single line:

ls -w 0

Output:

app-1.10.tar.gz  app-1.9.tar.gz  archive.tar.gz  backup.sql  data.csv  deploy.sh  docs  latest-notes  notes.txt  report.pdf  scripts

One older option you may encounter is --tabsize, which controls the number of columns used for tab characters in output. Modern GNU ls generally uses spaces for column alignment, so this option has limited practical value in everyday terminal use and can usually be ignored.

9. Display Numeric UID and GID with -n

File ownership is particularly important when transferring files between Linux servers, working with shared storage, or troubleshooting container permissions.

By default, ls -l displays usernames and group names by resolving the numeric user ID (UID) and group ID (GID) associated with each file. The -n option displays these numeric IDs instead, making it easier to identify the actual ownership values:

ls -ln notes.txt

Output:

-rw-r--r-- 1 1000 1000 6 Oct 27 10:25 notes.txt

Here, both the owner and group have the numeric ID 1000.

This is particularly useful when transferring files between servers using rsync or tar, working with NFS shares, or troubleshooting permissions inside containers.

For example, UID 1000 might belong to one user on your source server and a completely different user on the destination server. While ls -l displays the username resolved on the current system, ls -ln shows the numeric UID and GID without relying on those name lookups.

This makes -n a useful option when investigating ownership mismatches across systems.

10. Produce Null-Terminated Filenames with –zero

The previous options focus mainly on making directory listings easier to read. However, when using filenames in shell scripts or passing them between commands, ordinary ls output can create problems.

For example, a filename such as my report.txt contains a space. If a script or command splits filenames on whitespace, it may incorrectly treat this as two separate names.

GNU coreutils 9.0 introduced the --zero option, which separates filenames using a null character () instead of a newline. Since Linux filenames cannot contain null characters, this provides a reliable way to represent filenames without ambiguity.

You can combine --zero with xargs -0 to safely pass filenames containing spaces or other special characters to another command:

ls --zero *.txt | xargs -0 wc -c

Output:

 0 my report.txt
 6 notes.txt
 6 total

Unlike ordinary newline-separated output, null-separated output preserves each filename as a single argument, even when it contains spaces or newline characters.

For general-purpose scripting, however, find with -print0 is usually a better choice because it is designed for reliably traversing directory trees and handling filenames safely:

find . -maxdepth 1 -type f -name '*.txt' -print0 | xargs -0 wc -c

The advantage of ls --zero is that you can retain ls sorting options while producing null-separated filenames. For example, the following command lists matching files from newest to oldest while separating each filename with a null character:

ls --zero -t -- *.txt

This is useful when you specifically need ls features such as sorting by modification time but still want to pass filenames safely to another command.

If you’ve ever had a cleanup script stop on a file name with a space in it, share this with a teammate who writes shell scripts on shared servers.

Pro Tips for Using ls Options in Daily Work

Now that you’ve seen each option on its own, the most practical way to use them is to combine the ones you like into a few aliases, so you get the benefit without remembering every flag. A short set of lines in ~/.bashrc covers most daily needs:

export TIME_STYLE=long-iso
alias ll='ls -lh --group-directories-first'
alias lt='ls -lht'
alias lv='ls -1v'

Keep these aliases for interactive use only, and call ls with its full options inside scripts. Scripts run in a non-interactive shell that doesn’t load your aliases, so a script that relies on ll will fail on another server with ll: command not found.

When you list very large directories, such as a mail spool or a cache with hundreds of thousands of files, plain ls can take a long time because it reads and sorts every entry before printing anything. Using ls -U skips the sort and starts printing straight away, and adding -f also turns off colours and the extra stat calls they need.

Finally, if you share scripts with colleagues who run Ubuntu 26.04, test them against the uutils version of ls before relying on newer options like --zero or --hyperlink, since GNU-specific behaviour is the most likely place for differences to appear.

Conclusion

You now know how to make ls show readable timestamps and real creation times, sort files by version, size, and extension, list directories first, mark file types correctly with -F, and produce output that is safe to pass into scripts.

Most of these options turn a long pipeline into a single ls command, and the aliases above make the most useful ones part of your daily routine.

If you’d like to build the same depth of knowledge across the rest of your everyday toolkit, our 100+ Essential Linux Commands course on Pro Tecmint walks through the commands sysadmins use every day, with practical examples for each one.

And if you’re preparing for a sysadmin job, the Linux Interview Handbook covers 240+ questions, including the ls and file-management questions interviewers like to ask.

We’d love to hear which ls options you’ve added to your own ~/.bashrc. Do you use –group-directories-first in your aliases, or do you prefer a different tool such as eza for directory listings?

And if any of these options behaves differently on your distribution, feel free to post your ls --version output and the error in the comments so we can look at it together.

Similar Posts