-1

Under bash in Ubuntu, I want to ls -lah a directory and have it display file counts for directories recursively. That's to say I want it to count all files in the directories and their subdirectories.

Is this possible?

  • 1
  • @they No. I want each directory in the working directory to be printed with it's total file count, not to just point this and count one directory. – Duncan Marshall Oct 20 '21 at 16:28
  • I'm not sure how I'm supposed to try commands I don't know, or how an example would further explain what is a very simple concept. Does something still confuse you? – Duncan Marshall Oct 20 '21 at 18:46
  • 1
    You shouldn't randomly try commands, but a quick search will return various solutions in Stack Exchange that are at least similar to what you're trying to do and could serve as a starting point. Evidence that this question is not clear: (1) a duplicate that does not solve your problem was suggested, (2) an answer has been deleted, (3) the only answer you received tackles a bunch of slightly different scenarios. All this would be solved if you took the time to compose a minimal, reproducible example. – Quasímodo Oct 20 '21 at 19:51
  • Perhaps if you could just say what you don't understand. – Duncan Marshall Oct 21 '21 at 08:39
  • @DuncanMarshall I think the easiest way to clarify what you want to achieve would be to show us an example of small directory tree with subdirectories and files as well as the output you would expect from the command in question. The output of the command tree -F /SOME/DIR, where /SOME/DIR is to be replaced with the actual path (you als might have to install tree first), would go a long way to have a clear example in the question. – Adaephon Oct 29 '21 at 13:20

1 Answers1

2

I'm ignoring the request for the use of ls here as the output from that utility, on most Unixes, is generally only suitable for looking at.

The following would use find with bash to count the number of names in each subdirectory of the current directory, recursively.

find . -type d -exec bash -O nullglob -O dotglob -c '
    for dirpath do
        set -- "$dirpath"/*
        printf "%s:\t%d\n" "$dirpath" "$#"
    done' bash {} +

It calls bash with a batch of directory pathnames, and the in-line script iterates over the given batch and expands the * globbing pattern in each. With the nullglob and dotglob shell options set, this expands to a list of (possibly hidden) names, and $# is the length of that list.

If you just want the counts for the top-most directories in your current working directory:

shopt -s globstar nullglob dotglob
for dirpath in */; do
    set -- "$dirpath"/**
    printf '%s:\t%d\n' "$dirpath" "$#"
done

This is almost the same, except we no longer need to use find. We use ** to glob all names under each directory recursively and then display the results as before.

In fact, we could modify this ever so slightly to recreate the first piece of code without the need for find at all. Getting the count of names in each directory recursively:

shopt -s globstar nullglob dotglob
for dirpath in **/; do
    set -- "$dirpath"/*
    printf '%s:\t%d\n' "$dirpath" "$#"
done

Note that I only moved one * from one place to another.

Kusalananda
  • 333,661