The command find file*foo*txt
doesn't really use find
.
It's your shell who expands file*foo*txt
before find
even runs. Then find
gets possibly many arguments as its starting points; and no tests, no actions. The default action of -print
is assumed.
This is like printf '%s\n' file*foo*txt
. Both printf
and your find
only print what the shell supplies; except if there is no match. Or except if the shell returns a directory name (possibly among other names); in such case printf
will just print it, while find
will print it plus paths to every file in the directory, recursively.
Your task can be done with find
(not the shell) actually performing some matching. Use several -name
tests. The default behavior is to join tests with -a
(logical AND). This fits cases where you want the filename to match several patterns at once.
find . -type f -name 'file.*' -name '*.txt' -name '*.foo.*' -name '*.bar.*'
Notes:
- These patterns are not regular expressions.
*
here is a wildcard but .
is literal. I used .
because you wrote "file.foo.bar.txt
or file.bar.foo.txt
".
find
is recursive. Use -maxdepth 1
or (if your find
doesn't support it) read this: Limit POSIX find
to specific depth.
- Note the patterns are quoted. This is to protect them from being expanded by the shell (compare this question).
If you want literally file.foo.bar.txt
or file.bar.foo.txt
then use -o
(logical OR):
find . -type f \( -name file.foo.bar.txt -o -name file.bar.foo.txt \)
Note you often need parentheses with -o
. Without them -type f -name … -o -name …
would not do what we want.
And there is -regex
. It's a match on the whole path and there are several flavors.