Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .