Это find + gawk может сработать для вас:
find . -type f -print0 |
awk -v RS='\0' -F/ '{sub(/^.*\./, ".", $NF); ++freq[$NF]} END {for (i in freq) print freq[i], i}'
Безопасно использовать -print0 в find для обработки файлов с пробелами и другими специальными символами. Точно так же мы используем -v RS='\0' в awk, чтобы гарантировать, что байт NUL является разделителем записи.
Используйте однострочники Perl, чтобы сделать вывод в нужном вам формате, например:
find . -type f | perl -pe 's{.*[.]}{.}' | sort | uniq -c | perl -lane 'print join "\t", @F;' | sort -nr
Однострочник Perl использует следующие флаги командной строки: -e: говорит Perl искать код в строке, а не в файле. -n : перебирать ввод по одной строке за раз, назначая его $_ по умолчанию. -p : перебирать ввод по одной строке за раз, назначая его $_ по умолчанию. Добавляйте print $_ после каждой итерации цикла. -l: удалите разделитель строк ввода (по умолчанию "\n" в *NIX) перед выполнением кода в строке и добавьте его при печати. -a : разделить $_ на массив @F по пробелам или по регулярному выражению, указанному в опции -F.
СМОТРИТЕ ТАКЖЕ: perldoc perlrun: как запустить интерпретатор Perl: переключатели командной строки perldoc perlrequick: быстрое начало работы с регулярными выражениями Perl
Предположим, у вас есть известный каталог path со следующими подкаталогами foo, bar, baz, qux, quux, gorge, и мы хотим подсчитать типы файлов на основе расширения, но только для подкаталогов foo, baz и qux
Лучше всего просто сделать
$ find /path/{foo,baz,qux} -type f -exec sh -c 'echo "${0##*.}"' {} \; | sort | uniq -c
Часть exec просто использует простую замену переменной sh для печати расширения.
Что не работает? Вам не хватает точки перед расширениями файлов или вы хотите, чтобы вывод был отсортирован в числовом виде?