Best to learn about a command is to read its manual info ls
/info find
or man ls/man find
. Or the POSIX specification of each to learn about the subset that should be common to all different implementations.
The syntax for find
is
find [options] <file1> [<file2>...] [predicates]
(some find
implementations allow skipping <file1>
)
And ls
:
ls [options] [<file1> [<file2>...]]
(where [...]
denote optional parts).
Standard options are single letter and are introduced with -
. Some take arguments, some don't. Options can be combined in a single argument. For instance ls -l -d
can be written ls -ld
.
So you can see -exec
could never be an option, because find
would interpret it as -e -x -e -c
(or possibly -e -x ec
if the -x
option was taking arguments).
Some tool implementations support long options, but those are prefixed with --
instead of -
to avoid that conflict. For instance, GNU find
and GNU ls
both support the --help
option.
For find
, -exec
is what POSIX calls a predicate. It is not an option. It is part of the expression that comes after the list of files and is used to determine which files are selected and what to do on them.
find
also supports a few options (that come before the list of files) like -L
/-H
that affect its behaviour globally.
ls
has no concept of predicate nor expression used to select files. Its behaviour is only affected by the options. There's no option that will let ls
execute arbitrary commands.
There are a few problems with your code by the way:
-a
(implied when omitted) has precedence over -o
, so your -exec
would only be run for *.l
files. See `find` with multiple `-name` and `-exec` executes only the last matches of `-name`
- you used
-r
for grep
. That's a non standard option supported by some grep
implementations to do find
's job and find files inside directories. Though probably harmless here if none of the files found by find
are of type directory, it's probably not wanted.
- with the
{} \;
syntax, you're running one grep
per file. That's very inefficient and that also means grep
won't display the name of the files (unless -r
above kicks in)
- note that
-iname
is a non-standard extension (you may find it in info find
on your system if it's a GNU one, but you won't find it at the POSIX specification).
- as you're not using the
-type
predicate, find
will report any type of file, not just regular ones. That could include directories, devices, fifos... Using -type f
would restrict the search to regular files. With GNU find
, you can also use -xtype f
to select files that end up being regular after symlink resolution.
To address those, you could do:
find . -name '*.[cChl]' -type f -exec grep -in test1 /dev/null {} +
-exec
is an option specific tofind
and it is used to run other commands on the results returned from thefind
– Inian Aug 20 '19 at 05:59find . \( -iname '*.c' -o -name '*.h' -o -name '*.l' \) -exec grep -in test1 /dev/null {} +
orfind . -name '*.[cChl]' -exec grep -in test1 /dev/null {} +
– Stéphane Chazelas Aug 20 '19 at 06:02