0

I'd like to get a count of all files in a directory and its subdirectories but I don't want it to count .zip files. So I think something like this:

find . -iname "*.zip" -type f 2> /dev/null | wc -l

Except backwards - that would only return .zip files and I want to only count the other files.

Sam
  • 43

1 Answers1

5
LC_ALL=C find .//. ! -iname '*.zip' -type f 2> /dev/null |
  LC_ALL=C grep -c //

To count the regular files whose name doesn't end in .zip.

A few notes:

  • to negate a test in find expressions, just prepend ! to it. Some find implementations also support -not for that, though that's not standard nor portable.
  • you want to disable localisation for find (with LC_ALL=C) to find file names which end with .zip even if the filenames don't constitutes valid text in the user's locale. Also the uppercase character for i depends on the locale (in some it's I, in others it's İ). In the C locale, it's I. Using -name '*.[zZ][iI][pP]' would make it standard and more deterministic.
  • file paths can be made of several lines, using wc -l to count them doesn't make sense. Here, we use find .//. so to have something (//) unique to look for in each file path, which we're counting with grep -c. With GNU tools, you can also use find ... -print0 | sed -z '$=' though that would not give any output if there was 0 files found. find ... -print0 | tr -cd '\0' | wc -c would be better (but could have whitespace around the number). See also find ... -print0 | gawk -v 'RS=\0' 'END{print NR}'. Or with GNU find: find ... -printf . | wc -c.