5

I'm trying to find all the javascript files in subdirectories of my project.

The working tree is as follows:

.
├── app
├── assets
├── components
├── email.txt
├── gulpfile.js
├── node_modules
└── package.json

For that end I say:

find . -name *.js

or

find . -path *.js

Strangely, first command reports only gulpfile.js, while the second one reports nothing. But I have .js files in app, components and node_modules! Why wouldn't they show up?

Boris Burkov
  • 3,980

2 Answers2

8

Put single quotes around *.js. Without quotes, the shell is expanding the wildcard to filenames that match in the current directory, so find only gets those filenames, either in the current directory or sub-directories in the find spec (but never sees the wildcard). To specify it as a pattern for find to use, you need to prevent the shell expansion. '*.js' does that.

2

It's easy to forget that shell globbing still plays a role in the process. Thus you need a way to tell shell to avoid expanding * to a list of files. One way is via what Chris Johnson mentioned - quoting.

Another is via escaping the * character, as in

find . -iname \*.js

Compare:

$ strace -e trace=execve find -maxdept 1 -iname *.js > /dev/null                                      
execve("/usr/bin/find", ["find", "-maxdept", "1", "-iname", "file1.js", "file2.js"], [/* 75 vars */]) = 0
find: unknown predicate `-maxdept'
+++ exited with 1 +++

$ strace -e trace=execve find -maxdept 1 -iname \*.js > /dev/null                                     
execve("/usr/bin/find", ["find", "-maxdept", "1", "-iname", "*.js"], [/* 75 vars */]) = 0
find: unknown predicate `-maxdept'
+++ exited with 1 +++

In first case we see that * was expanded to list of files file1.js and file2.js that are present in the current working directory. In second example - the * is treated as literal argument to find. In fact, this is the same result produced by quoting the argument:

$ strace -e trace=execve find -maxdept 1 -iname '*.js' > /dev/null                                    
execve("/usr/bin/find", ["find", "-maxdept", "1", "-iname", "*.js"], [/* 75 vars */]) = 0
find: unknown predicate `-maxdept'
+++ exited with 1 +++

Alternatively , you could use the octal value of * instead.

$ strace -e trace=execve find -maxdept 1 -iname $'\52'.js > /dev/null                                 
execve("/usr/bin/find", ["find", "-maxdept", "1", "-iname", "*.js"], [/* 75 vars */]) = 0
find: unknown predicate `-maxdept'
+++ exited with 1 +++