19

I am using the following command for counting the lines of text in JAVA files:

find . -name '*.java' | xargs wc -l

How can I modify the find command parameters to match more than one file extension? For example, I would like use the above operation for CPP, C, and H files.

2
  • This question is actually about the find command, since that is where you are searching for matching files. – iglvzx Apr 24 '12 at 23:48
  • 1
    Also, use either the find -print0 | xargs -0 construct or even better and simpler: find . -name '*.cpp' -o -name '*.c' -o -name '*.h' -exec wc -l {} +. This will avoid any file name issues (blank spaces, new lines and so on) and is (very) good custom. – Daniel Andersson Apr 25 '12 at 6:39
21

Use the -o option for an OR. For example, this would list .cpp, .c and .h files:

find . -name \*.cpp -o -name \*.c -o -name \*.h
3
  • Ah. The * no longer needs to be escaped if formatted as code. Totally overlooked that. :) – iglvzx Apr 25 '12 at 0:44
  • Yep, it took three edits by two people but we got it. – JOTN Apr 25 '12 at 1:06
  • 3
    This didn't work for me on OSX (only matched the last -name *.ext) -- I had to use parentheses as suggested by @smokinguns below. – Gilead May 8 '15 at 11:37
2

You will need to use the -o option. For example the statement below finds all png, jpg and gif files in a folder.

find . \( -iname \*.png -o -iname \*.jpg -o -iname \*.gif \)

I use the -iname option so that the match is case insensitive.

1
  • 1
    iname isn't available on all versions of find. – JOTN Apr 25 '12 at 1:07
2
$ find /path/ -name '*.cpp' -or -name '*.c' -or -name '*.h'

The “-or” says I’m looking for either/both of two sets.

I recently wrote a quick guide to using find with boolean operators here: http://jamesfishwick.com/2012/linux-find-and-boolean-operators

1

While all answers are more or less the same, I don't find them readable with multiple name and Boolean operators in-between.

I think this may be more elegant solution:

$ find . -type f | grep -E "\.java$|\.cpp$|\.c$"

Let's break this up

  • find . finds all files recursively in current path (change to some other path if you need)
  • -type fnarrows the search only to files (not too much of a speed gain, but still...)
  • | grep -E I used this to get grep recognize or (|) operator in Mac OS X which uses FreeBSD grep, GNU grep does not need that (check in your man file).
  • "\.java$|\.cpp$|\.c$" regular expression which includes files whose name ends with .java, .cpp, and .c (add ones you need)

You can then pipe the resulting list for further processing, e.g.

$ find . -type f | grep -E "\.java$|\.cpp$|\.c$" | xargs sed -i '' $'/s/\r$//'

This example removes DOS/Windows CRLF line ending for OS X/Linux LF (this is also OS X sed syntax, check for your version specifics).

2
  • I wanted to find all video file types using 25 different extension matching parameters. This was the only approach that worked for me. (Ubuntu 14.04 LTS) – Elder Geek Nov 2 '16 at 14:35
  • How well does this perform when you only have a small number of matching files on a large file system with lot of files that don't match the grep pattern? – dvvrt Jan 7 at 16:08
0

Use

find path/to/dir -name "*.ext1" -o -name "*.ext2"

Explanation

  1. The first parameter is the directory you want to search.
  2. By default find does recursion.
  3. The -o stands for -or. So above means search for this wildcard OR this one. If you have only one pattern then no need for -o.
  4. The quotes around the wildcard pattern are required.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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