bug#79710: [PATCH] ls: add --count and --count-list options to display file, directory, and symlink counts and counts with list of contents
Debkanta Mondal <[email protected]>
| Newsgroups | gmane.comp.gnu.core-utils.bugs |
|---|---|
| Message-ID | <CAJPp_T=ekw7k02vEYuRk3CNCXHfcSa0OJVR0fxFhgFMTrv0FHw@mail.gmail.com> |
Hello Coreutils maintainers,
I have attached cleaned logic specific patch file for --count and
--count-list and also
NEWS patch file for detailed explanation from my side to propose
these changes still after having "ls | wc" with this mail.
Output: If current directory have 5 files, 2 directories and 0 link: then
ls --count
Directories: 2 | Files: 5 | Links: 0
ls --count-list
Directories: 2 | Files: 5 | Links: 0
----------------------------------------------------------------------------------------
CONTAINING ELEMENTS ARE
----------------------------------------------------------------------------------------
Name Type Permissions Size
Modified
----------------------------------------------------------------------------------------
ABOUT-NLS FILE -rw-r--r-- 93787 2023-03-13 23:42
AUTHORS FILE -rw-r--r-- 3827
2023-03-13 23:38
COPYING FILE -rw-r--r-- 35149
2023-03-13 23:38
ChangeLog FILE -rw-r--r-- 324062
2023-04-18 20:02
GNUmakefile FILE -rw-r--r-- 4589
2023-04-18 19:39
build DIR drwxr-xr-x 160
2025-10-28 23:56
build-aux DIR drwxr-xr-x 800
2023-04-18 20:02
Why do we need a --count option when we have 'ls | wc'"?
ls --count will count the number of directories, files and symlinks
of current directory user present. and --count-list will print the
count and also print containing items details - like name, size,
permissions, modified datetime, and its type. With --count, you get
everything in one place: directories, files, links, and the table,
without needing to chain commands like ls | wc. It’s simpler, more reliable,
and avoids issues with pipes or parsing output. And --count-list can
give a detailed table of contained elements with type wise count and
all within the ls , just using options flag , no need extra pipeline/
complex command for this simple and frequently required output
The patch was tested on coreutils-9.3 using `make check`, and all tests passed.
Thank you for maintaining Coreutils and for reviewing my contribution!
Signed-off-by: Debkanta Mondal ([email protected])
On Tue, Oct 28, 2025 at 11:27 PM Collin Funk <[email protected]> wrote:
>
> Pádraig Brady <[email protected]> writes:
>
> > On 28/10/2025 15:45, Debkanta Mondal wrote:
> >> my-count-and-count-list-ls-update.patch
> >> Hello Coreutils maintainers,
> >> This patch adds two new options to `ls`:
> >> --count : Display the total number of directories, files and
> >> symbolic links.
> >> --count-list : Display a detailed count + list of directories,
> >> files and symbolic links present in the current directory.
> >> The purpose of this update is to make it easier for users to quickly
> >> see
> >> object counts when listing directory contents.
> >> The patch was tested on coreutils-9.3 using `make check`, and all
> >> tests passed.
> >> I have attached the patch file with this email.
> >> Thank you for maintaining Coreutils and for reviewing my
> >> contribution!
> >> Signed-off-by: Debkanta Mondal ([email protected])
> >
> > It's hard to review this patch as it's mostly reindented changes.
> > Can you resend with just the logic changes.
>
> Likewise. The HACKING file has good formatting settings for vim.
>
> The Emacs settings could be improved to add '(c-set-style "GNU")', among
> other things.
>
> Other editors I have tried are bad at GNU formatting.
>
> > Can you give example outputs from the new options.
> > Note new options to ls have a high bar.
>
> My feeling is that the feature is not really needed with GNU find:
>
> $ find . -maxdepth 1 -type d | wc -l
> 39
> $ find . -maxdepth 1 -type f | wc -l
> 35
> $ find . -maxdepth 1 -type l | wc -l
> 2
>
> Collin
ls-count-cleaned.patch
(application/octet-stream, 6.4 KB)
--- /Users/debkantamondal/coreutils-original/src/ls.c 2023-03-13 23:38:10
+++ /Users/debkantamondal/coreutils-9.3/src/ls.c 2025-10-28 23:45:27
@@ -282,6 +282,8 @@
static void indent (size_t from, size_t to);
static size_t calculate_columns (bool by_columns);
static void print_current_files (void);
+static void count_elements_in_container();
+static void containers_list();
static void print_dir (char const *name, char const *realname,
bool command_line_arg);
static size_t print_file_name_and_frills (const struct fileinfo *f,
@@ -522,6 +524,10 @@
/* Human-readable options for output, when printing block counts. */
static int human_output_opts;
+/* --count and --coun-list options control */
+static bool count_mode = false;
+static bool count_mode_with_list = false;
+
/* The units to use when printing block counts. */
static uintmax_t output_block_size;
@@ -829,6 +835,8 @@
enum
{
AUTHOR_OPTION = CHAR_MAX + 1,
+ COUNT_OPTION,
+ COUNT_OPTION_WITH_LIST,
BLOCK_SIZE_OPTION,
COLOR_OPTION,
DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION,
@@ -894,6 +902,8 @@
{"block-size", required_argument, NULL, BLOCK_SIZE_OPTION},
{"context", no_argument, 0, 'Z'},
{"author", no_argument, NULL, AUTHOR_OPTION},
+ {"count", no_argument, NULL, COUNT_OPTION},
+ {"count-list", no_argument, NULL, COUNT_OPTION_WITH_LIST},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -1543,9 +1553,111 @@
/* If execution reaches here, then the program has been
continued (after being suspended). */
+ }
+}
+
+static void count_elements_in_container()
+{
+ size_t file_count = 0, dir_count = 0, link_count = 0;
+
+ for (size_t i = 0; i < cwd_n_used; i++)
+ {
+ struct fileinfo *f = sorted_file[i];
+
+ // Ensure we have stat info
+ if (!f->stat_ok)
+ {
+ if (lstat(f->name, &f->stat) == 0)
+ f->stat_ok = true;
+ }
+
+ if (!f->stat_ok)
+ continue;
+
+
+
+ mode_t mode = f->stat.st_mode;
+
+ if (S_ISDIR(mode))
+ dir_count++;
+ else if (S_ISLNK(mode))
+ link_count++;
+ else if (S_ISREG(mode))
+ file_count++;
}
+
+ printf("Directories: %zu | Files: %zu | Links: %zu",
+ dir_count, file_count, link_count);
+ if (count_mode_with_list)
+ printf("\n-------------------------------------------------------------------------------\n");
+ else
+ printf("\n");
}
+static void containers_list()
+{
+ // for (size_t i = 0; i < cwd_n_used; i++)
+ printf("CONTAINING ELEMENTS ARE\n-------------------------------------------------------------------------------\n");
+ // print_current_files();
+ printf("%-30s %-6s %-12s %-10s %-20s\n",
+ "Name", "Type", "Permissions", "Size", "Modified");
+ printf("-------------------------------------------------------------------------------\n");
+
+ for (size_t i = 0; i < cwd_n_used; i++)
+ {
+ struct fileinfo *f = sorted_file[i];
+
+ // Ensure stat info
+ if (!f->stat_ok)
+ {
+ if (lstat(f->name, &f->stat) == 0)
+ f->stat_ok = true;
+ }
+
+ if (!f->stat_ok)
+ continue;
+
+ // File type
+ const char *type = "?";
+ if (S_ISDIR(f->stat.st_mode))
+ type = "DIR";
+ else if (S_ISREG(f->stat.st_mode))
+ type = "FILE";
+ else if (S_ISLNK(f->stat.st_mode))
+ type = "LINK";
+
+ // Permissions string
+ char perms[11];
+ mode_t m = f->stat.st_mode;
+ perms[0] = S_ISDIR(m) ? 'd' : (S_ISLNK(m) ? 'l' : '-');
+ perms[1] = (m & S_IRUSR) ? 'r' : '-';
+ perms[2] = (m & S_IWUSR) ? 'w' : '-';
+ perms[3] = (m & S_IXUSR) ? 'x' : '-';
+ perms[4] = (m & S_IRGRP) ? 'r' : '-';
+ perms[5] = (m & S_IWGRP) ? 'w' : '-';
+ perms[6] = (m & S_IXGRP) ? 'x' : '-';
+ perms[7] = (m & S_IROTH) ? 'r' : '-';
+ perms[8] = (m & S_IWOTH) ? 'w' : '-';
+ perms[9] = (m & S_IXOTH) ? 'x' : '-';
+ perms[10] = '\0';
+
+ // Size
+ long size = (long)f->stat.st_size;
+
+ // Modified time
+ char mod_time[20];
+ struct tm *tm_info = localtime(&f->stat.st_mtime);
+ strftime(mod_time, sizeof(mod_time), "%Y-%m-%d %H:%M", tm_info);
+
+ // Print row (with optional color)
+ set_normal_color();
+ printf("%-30s %-6s %-12s %-10ld %-20s\n",
+ f->name, type, perms, size, mod_time);
+ }
+ printf("\n");
+}
+
+
/* Setup signal handlers if INIT is true,
otherwise restore to the default. */
@@ -1844,7 +1956,19 @@
j = interrupt_signal;
if (j)
raise (j);
+ }
+ /* --count: show number of files, directories, and symlinks */
+ if (count_mode)
+ {
+
+ count_elements_in_container();
+
+ if (count_mode_with_list)
+ {
+ containers_list();
}
+ }
+
if (dired)
{
@@ -2124,8 +2248,17 @@
case AUTHOR_OPTION:
print_author = true;
+ break;
+
+ case COUNT_OPTION:
+ count_mode = true;
break;
+ case COUNT_OPTION_WITH_LIST:
+ count_mode = true;
+ count_mode_with_list = true;
+ break;
+
case HIDE_OPTION:
{
struct ignore_pattern *hide = xmalloc (sizeof *hide);
@@ -3097,7 +3230,7 @@
"sort_type == sort_none" for its initialization
of the sorted_file vector. */
sort_files ();
- print_current_files ();
+ if (!count_mode) print_current_files ();
clear_files ();
}
}
@@ -3146,7 +3279,7 @@
}
if (cwd_n_used)
- print_current_files ();
+ if (!count_mode) print_current_files ();
}
/* Add 'pattern' to the list of patterns for which files that match are
@@ -5588,7 +5721,19 @@
\n\
\n\
"), stdout);
+fputs (_("\
+ --count will print total counts of files, dirs, and links before listing.\
+ \n\
+"),
+ stdout);
fputs (_("\
+ --count-list will print counts of files, dirs and links and \n\
+ also list down all the containing files, dirs and links for current directory.\
+ \n\
+ \n\
+"),
+ stdout);
+ fputs (_("\
-Q, --quote-name enclose entry names in double quotes\n\
"), stdout);
fputs (_("\
NEWS-for-count.patch
(application/octet-stream, 1.2 KB)
--- /Users/debkantamondal/coreutils-original/NEWS 2023-04-18 19:38:11 +++ /Users/debkantamondal/coreutils-9.3/NEWS 2025-10-29 00:28:04 @@ -156,6 +156,17 @@ ls --color now matches a file extension case sensitively if there are different sequences defined for separate cases. + ls --count will count number of directories, files and symlinks + of current directory user present. and --count-list will print the + count and also print containing items details - like name, size, + permissions, modified datetime, and its type. With --count, you get + everything in one place: directories, files, links, and the table, + without needing to chain commands like ls | wc. It’s simpler, more reliable, + and avoids issues with pipes or parsing output. And --count-list can + give a detailed table of contained elements with type wise count and + all within the ls , just using options flag , no need extra pipeline/ + complex command for this simple and frequently required output + printf unicode \uNNNN, \UNNNNNNNN syntax, now supports all valid unicode code points. Previously is was restricted to the C universal character subset, which restricted most points <= 0x9F.