This question already has an answer here:

Want to list all python test scripts that contain "def test"

This command line did not work while individual command works

find . -name "*.py" | grep "def test"

marked as duplicate by don_crissti, jimmij, Sparhawk, Christopher, Kusalananda Feb 14 at 20:26

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.



grep -r --include '*.py' 'def test'
  • -r tells grep to search for files recursively

  • --include '*.py' tells grep to only examine files whose names end in .py.

The --include option is supported by both GNU (Linux) grep and MacOS grep

Discussion of pipeline approach

In the following command, find passes the names of the files found to standard input of grep:

find . -name "*.py" | grep "def test"

The issue here is that grep treats its standard input as the text to search. Consequently, the only output will be those files whose name (as opposed to contents) contains def test.

For example, let's create an empty file:

$ touch 'def test.py'

And run the pipeline command:

$ find . -name "*.py" | grep "def test"
./def test.py

The command finds this file because of its name. Its contents are never examined.

  • 1
    ... if your grep supports --include like GNU grep does. – Bodo Feb 12 at 19:12
find . -name '*.py' -exec grep -l 'def test' {} \;


find . -name '*.py' -exec grep -l 'def test' {} +

The second version will result in fewer invocations of grep by specifying sets of files as arguments.

grep -ril 'def test' .

The above command would list what you are looking.

In the command - the options ril refer to recursive(r) case insensitive(i) search and list(l) only file names


The standard way to execute a command on files found by find is using xargs:

find . -name "*.py" | xargs grep "def test"

In case of grep, you can use recursive grep instead of find + grep as other answers have explained, but xargs is good to know because it's a general approach that can be used for other use cases too.

(And as Doug O'Neal commented: if there are filenames with spaces, you have to tell find and xargs to use null characters as terminators: find . -name "*.py" -print0 | xargs -0 grep "def test")

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