Skip to content

ls: Add a --header option - #344

Open
AJRepo wants to merge 1 commit into
coreutils:masterfrom
AJRepo:ls_headers
Open

AJRepo wants to merge 1 commit into
coreutils:masterfrom
AJRepo:ls_headers

Conversation

@AJRepo

@AJRepo AJRepo commented Sep 6, 2026 •

Copy link
Copy Markdown

Feature Request:

Add a new option to display column titles when using the -l flag

This is following up on the comment at https://lists.gnu.org/archive/html/coreutils/2023-03/msg00086.html by Pádraig that adding headers to ls bears merit.

Headers:

  • Inode: (enabled by -i)
  • Blocks: (enabled by -s)
  • Mode: (POSIX / coreutils convention for file mode & permissions)
  • Links: (hard link count)
  • Owner: (suppressed by -g)
  • Group: (suppressed by -G / -o)
  • Author: (enabled by --author)
  • Context: (enabled by -Z)
  • Size: (byte size or human-readable size or device numbers)
  • Date: (timestamp column; accommodates default, ISO, and full-iso styles)
  • Name: (file name)

Alignment:

  • Columns that are numbers are right aligned
  • Columns that are text are left aligned.

Tests:

./src/ls -l --header
./src/ls -il --header
./src/ls -sl --header
./src/ls -isl --header
./src/ls -g --header
./src/ls -o --header
./src/ls -og --header
./src/ls -n --header
./src/ls -l --author --header
./src/ls -l --full-time --header
./src/ls -l -D --header
./src/ls -l --header file1 file2
./src/ls -lR --header directory/

Test suite tests: tests/ls/header.sh:

  • Test suite verifying: alignment and presence with options:
    • ls -l --header: with columns (Mode Links Owner Group Size Date Name).
    • ls -il --header: Add Inode column
    • ls -sl --header: Add Blocks column
    • ls -isl --header: Add both Inode and Blocks.
    • ls -g --header / ls -o --header / ls -og --header: omission of Owner/Group.
    • ls -n --header: numeric UID/GID column header
    • ls -l --header --author: Add author column.
    • ls -l --header --full-time: full timestamp
    • ls -l --header file1 file2: without total line.
    • ls -lR --header: recursive directory headers.
    • ls --header without -l: do not display without -l flag.

Examples:

$ ./src/ls -l --header | head 
total 12452
Mode       Links Owner Group    Size Date         Name
-rw-r--r--     1 afan  afan    93787 Sep  6 07:55 ABOUT-NLS
-rw-rw-r--     1 afan  afan    64533 Sep  6 07:56 aclocal.m4
-rw-rw-r--     1 afan  afan     3839 Sep  6 07:51 AUTHORS
drwxr-xr-x     2 afan  afan     4096 Sep  6 07:56 autom4te.cache
-rwxrwxr-x     1 afan  afan    57522 Sep  6 07:51 bootstrap
-rw-rw-r--     1 afan  afan     8806 Sep  6 07:51 bootstrap.conf
drwxrwxr-x     2 afan  afan     4096 Sep  6 08:37 build-aux
-rw-rw-r--     1 afan  afan    41184 Sep  6 07:51 cfg.mk

$ ./src/ls -il --header | head 
total 12452
   Inode Mode       Links Owner Group    Size Date         Name
26636174 -rw-r--r--     1 afan  afan    93787 Sep  6 07:55 ABOUT-NLS
26638483 -rw-rw-r--     1 afan  afan    64533 Sep  6 07:56 aclocal.m4
26621778 -rw-rw-r--     1 afan  afan     3839 Sep  6 07:51 AUTHORS
26621764 drwxr-xr-x     2 afan  afan     4096 Sep  6 07:56 autom4te.cache
26621795 -rwxrwxr-x     1 afan  afan    57522 Sep  6 07:51 bootstrap
26621796 -rw-rw-r--     1 afan  afan     8806 Sep  6 07:51 bootstrap.conf
26621797 drwxrwxr-x     2 afan  afan     4096 Sep  6 08:37 build-aux
26621802 -rw-rw-r--     1 afan  afan    41184 Sep  6 07:51 cfg.mk

 ./src/ls -isl --header | head 
total 12452
   Inode Blocks Mode       Links Owner Group    Size Date         Name
26636174     92 -rw-r--r--     1 afan  afan    93787 Sep  6 07:55 ABOUT-NLS
26638483     64 -rw-rw-r--     1 afan  afan    64533 Sep  6 07:56 aclocal.m4
26621778      4 -rw-rw-r--     1 afan  afan     3839 Sep  6 07:51 AUTHORS
26621764      4 drwxr-xr-x     2 afan  afan     4096 Sep  6 07:56 autom4te.cache
26621795     60 -rwxrwxr-x     1 afan  afan    57522 Sep  6 07:51 bootstrap
26621796     12 -rw-rw-r--     1 afan  afan     8806 Sep  6 07:51 bootstrap.conf
26621797      4 drwxrwxr-x     2 afan  afan     4096 Sep  6 08:37 build-aux
26621802     44 -rw-rw-r--     1 afan  afan    41184 Sep  6 07:51 cfg.mk



I understand that the preferred process for sending changes
is to email [email protected] or [email protected] respectively.
However, as a first attempt at submitting a patch to such an important repo, I'd prefer to see if this
is acceptable first.

Copyright Assignment

I assign copyright of this to the FSF. I have submitted the email to [email protected]

Add a new option to display column titles when using the -l flag

Signed-off-by: A Ottenheimer <[email protected]>
@AJRepo

AJRepo commented Sep 22, 2026 •

Copy link
Copy Markdown
Author

Some additional testing of the TIME_STYLE parameter with old and newer files, I found
the default behavior of ls -l is to expect both old and new TIME_STYLE to be the same width
and so pulls the default width from the first specified (old_file style). That meant that the
alignment of the header row could be off depending on which style (old, new) was longer.

I have fixed that and will force update this PR in a short while.

New test:

#!/bin/bash
touch new_file
touch -d 2018-01-01 old_file

echo "Testing new ls headers"
./src/ls -l --header --time-style=$'+%Y-%m-%d\n%Y-%m-%d %H:%M:%S' old_file new_file
./src/ls -l --header --time-style=$'+%Y-%m-%d %H:%M:%S\n%Y-%m-%d' old_file new_file

echo -e "\nTesting new ls **bold** headers"
./src/ls -l --header --time-style=$'+\e[1m%Y-%m-%d\e[0m\n%Y-%m-%d %H:%M:%S' old_file new_file
./src/ls -l --header --time-style=$'+\e[1m%Y-%m-%d %H:%M:%S\e[0m\n%Y-%m-%d' old_file new_file

echo -e  "\nTesting new ls no headers"
./src/ls -l --time-style=$'+%Y-%m-%d\n%Y-%m-%d %H:%M:%S' old_file new_file
./src/ls -l --time-style=$'+%Y-%m-%d %H:%M:%S\n%Y-%m-%d' old_file new_file

With output

Testing new ls headers
Mode       Links Owner Group Size Date                Name
-rw-rw-r--     1 afan  afan     0 2026-09-22 13:54:44 new_file
-rw-rw-r--     1 afan  afan     0 2018-01-01          old_file
Mode       Links Owner Group Size Date                Name
-rw-rw-r--     1 afan  afan     0 2026-09-22          new_file
-rw-rw-r--     1 afan  afan     0 2018-01-01 00:00:00 old_file

Testing new ls **bold** headers
Mode       Links Owner Group Size Date                Name
-rw-rw-r--     1 afan  afan     0 2026-09-22 13:54:44 new_file
-rw-rw-r--     1 afan  afan     0 2018-01-01  old_file
Mode       Links Owner Group Size Date       Name
-rw-rw-r--     1 afan  afan     0 2026-09-22 new_file
-rw-rw-r--     1 afan  afan     0 2018-01-01 00:00:00 old_file

Testing new ls no headers
-rw-rw-r-- 1 afan afan 0 2026-09-22 13:54:44 new_file
-rw-rw-r-- 1 afan afan 0 2018-01-01 old_file
-rw-rw-r-- 1 afan afan 0 2026-09-22 new_file
-rw-rw-r-- 1 afan afan 0 2018-01-01 00:00:00 old_file

Issues:

  • Should ls -l (without the header) be also modified to align if old and new time_styles are different?
    I'm assuming even if "yes" that would be a different PR or bug report and leaving as-is.

  • mbsnwidth() rejects the bold (ASCII escape sequences) as non-printable so doesn't generate a width

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant