4

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.

2 Answers 2

5

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).

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

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

You must log in to answer this question.

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