I am looking for a simple shell function (bash prefered) to list all file extensions in an arborescence and count the number of occurences of each.

For example, list_extensions . would return something like :

pdf 134
tex 42
cpp 30

A plus would be to also count the file without extensions.

  • @don_crissti Thanks ! The first link does the job. Do you know how I could address the "files without extensions" problem ?
    – bela83
    May 3 '15 at 15:44
  • I'd use something like find . -type f ! -name '*.*' -print0 | grep -cz . to count them. May 3 '15 at 16:10
  • @don_crissti Would you care to expand on the cz flags ? I would gladly accept this as an answer.
    – bela83
    May 4 '15 at 8:07
  • 1
    It's there (together with -print0) to deal with file names containing newlines, e.g. find prints the file names null delimited and grep counts the matching lines treating them as null delimited (-z) instead of newline delimited. If you don't have such file names you can simply run find . -type f ! -name '*.*' | grep -c . or find . -type f ! -name '*.*' | wc -l which means print all file names that don't have a dot in their name (one per line) and then count the lines. May 4 '15 at 20:28

As don_crissti stated in a comment, this question is a duplicate and the answer can be found here. However, you also want to count files without extensions. This is my go at it:

echo no_ext $(find . -type f -exec sh -c 'echo $(basename "{}")' \; | grep -v '\.' | wc -l)

I'll try to explain the subsequent commands and their purpose.

First, we use find to find regular files and forward their respective paths through the basename command in a rather cumbersome way.

find . -type f -exec sh -c 'echo $(basename "{}")' \;

Secondly, we can then simply search for filenames without a period in them, using grep in invert mode.

grep -v

The last step is to count the number of rows.

wc -l

This can be feeded into echo. Combining all of this results in the command above.

EDIT: I use command substitution to concatenate a label, in this case 'no_ext' to the computed number. You can also run the command between the parentheses by itself without the echo to only print the computed number.

  • Very good. I understand well find grep and wc. But what is the use of the construct echo no_ext $() ?
    – bela83
    May 4 '15 at 8:05
  • In unix shells, like bash, you can use either the used dollar notation or, equivalently, use the backtick notation (like: echo no_ext find . -type ...) to perform command substitution. This causes the command to be executed and be substituted with it's output in-place. Or in other words: I am printing 'no_ext' (for 'no extension') using echo and I concatenate to it the output of the long command (the number of files without extension). May 4 '15 at 12:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.