17

I'd like to find source files (*.c, *.cpp, *.h) that contain in Linux/MinGW/Cygwin, and recursively in all sub directories.

My basic idea is using find and grep. However, building a regular expression that can check given file name is either *.c, *.cpp, or *.h isn't easy. Could you help me out?

7 Answers 7

18

This should work:

find Linux/MinGW/Cygwin -name '*.c' -o -name '*.cpp' -o -name '*.h'
6

You can use:

find . -regex '.*/.*\.\(c\|cpp\|h\)$'
2
  • What does the $ at the end of the command do?
    – Ali
    Aug 15, 2017 at 3:16
  • 2
    @Ali: It anchors the regex to the end of the line (it prevents finding files named foo.cpp.old for example). Aug 23, 2017 at 13:12
2

I would use:

find . -regex '.*\.\(c\|cpp\|h\)$' -print
1
  • 1
    In my macbook, the script without a -E can't find anything. you might need add a -E (as extended) to make it more portable, just like find -E . -regex '.*\.(c|h|cpp)' -print. ;-)
    – pambda
    May 1, 2017 at 9:17
2

Quick and dirty, and avoids directory names:

find . -type f -name *.[c\|h]
1
  • 2
    There are three problems with this command: 1. It won't find *.cpp files. 2. It will find *.| files. 3. The glob will expand if there are matching files in the current directory. Quoting prevents that.
    – Dennis
    Dec 17, 2013 at 15:48
2

You can use a slightly simpler regex:

find . -type f -regex ".*\.[ch]\(pp\)?$"
1

I use a mac pro which also works in bash. But every time I type in the command line:

find -name

it says illegal option. So I just simplified it as:

find *.c *.cpp *.h

and found it really worked!

1
  • I don't think that does what you think. I think the shell is expanding the * before being passed to find. What you end up with is something like find file1.c file1.h file2.c, etc. , and only for files in the current directory, not any sub-directories. The shell only expands * to the names of files in the current directory. You can just use ls for that. Sep 19, 2022 at 15:25
0

On my mac book pro {macOS Catalina}, the following did the trick:

find . | grep ".*/.*\.\(c\|cpp\|h\)$"

You must log in to answer this question.

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