Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How do I recursively count all files of a certain type in zsh?

There are quite a few methods to do this (helpful SuperUser questions such as this one give pointers), but few zsh-specific methods.

This follows my previous question - several zsh-specific solutions have been given to me, so I will record them here in case anybody else ever wants to do this.

share|improve this question
up vote 3 down vote accepted

The zsh-specific feature is zsh globbing; I don't fully understand it, but these work.

  1. $ a=( */.(cpp|h)(.) ); print $#a

    Will count all files ending in .cpp and .h recursively from the current directory, then print the result as a single number.

  2. From this answer, I can also use:

    $ ls */.{cpp,h} | wc -l

The zsh specific part, then, is the expansion of **/*.{cpp,h} to match files ending in .cpp and .h. I haven't yet found any (simple) comprehensive of zsh globbing that I've been able to understand (although this explains the use of **/*.{a,b} fairly well).

share|improve this answer
zsh kinda defies "simple"; it's got a lot of functionality and it's hard to describe most of it simply. – geekosaur Apr 9 '12 at 12:57
explanation of 1. ( */.(cpp|h)(.) ) sets a as an array of all files matching the glob, and $#a gives its size – CharlesB Nov 14 '12 at 10:56

To count no matches correctly: a=( */.(cpp|h)(.N) ); print $#a

To avoid leaking the variable: local -a a; a=( */.(cpp|h)(.N) ); print $#a

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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