How do I find a file containing using wildcard on Linux? - linux

I would like to know if it is possible to use find with wildcards:
I use this command, but I have an error
find -type f -name /target/*.zip

You need to put the wildcard in quotes, otherwise it gets expanded by the shell before the command is run.
And it should just be a filename, not a pathname. The directory to start searching should be an argument to find before the filter specifications.
find /target -type f -name '*.zip'

Related

find type -f also returns non-matching files in matching directory

all files/folders in current directory:
./color_a.txt
./color_b.txt
./color_c.txt
./color/color_d.txt
./color/blue.txt
./color/red.txt
./color/yellow.txt
command used to find all files with the word color in name:
find ./*color* -type f
result:
./color_a.txt
./color_b.txt
./color_c.txt
./color/color_d.txt
./color/blue.txt
./color/red.txt
./color/yellow.txt
expected result:
./color_a.txt
./color_b.txt
./color_c.txt
./color/color_d.txt
The result also includes all the non-matching file names under a matching parent directory.
How could I get ONLY files with names directly matching the color pattern?
Thanks a lot!
What you probably want for filename filtering is a simple -name <glob-pattern> test:
find -name '*color*' -type f
From man find:
-name pattern
Base of file name (the path with the leading directories removed) matches shell
pattern pattern. Because the leading directories are removed, the file names
considered for a match with -name will never include a slash, so `-name a/b' will
never match anything (you probably need to use -path instead).
Just as a side note, when you wrote:
find ./*color* -type f
the shell expanded the (unquoted) glob pattern ./*color*, and what was really executed (what find saw) was this:
find ./color ./color_a.txt ./color_b.txt ./color_c.txt -type f
thus producing a list of files in all of those locations.
You can use the regex option
find -regex ".*color_.*" -type f

Why does find . -name foo* fail?

OK, probably a stupid question, but why doesn't this work?
find . -name Orna* -ls
It seems that "find" should be able to handle this simple request... Am I missing something here? This should be a basic execution of the "find" command, but linux is being stupid, or maybe I am.
correct way of using Find Command are the following phrases
find . -type f -name "filename" # this command used to find files from the curent dir
find . -type d -name "dir name" # this command used to find dirs from the curent dir
find /. -type f -name "filename" # this command used to find files from the system
find /. -type d -name "dir name" # this command used to find dirs from the system
I wish it be a helpful for you
You need to quote the name parameter so the shell doesn't expand the wildcard, e.g.
find . -name "Orna*" -ls
To explain the "why" a little more than existing answers do -- wildcards are expanded by the shell before the command being invoked is run. Thus, let's say your current directory contains files Orna1 and Orna2.
In that case, when you run
find . -name Orna* -ls
...what's actually invoked by the shell is:
find . -name Orna1 Orna2 -ls
...thus, find never sees the wildcard expression at all!
Quoting the expansion, as in:
find . -name 'Orna*' -ls
...prevents the shell from trying to expand the wildcard before running your command, thus preventing this issue.

Copy specific files recursively

This problem has been discussed extensively but I couldn't find a solution that would help me.
I'm trying to selectively copy files from a directory tree into a specific folder. After reading some Q&A, here's what I tried:
cp `find . -name "*.pdf" -type f` ../collect/
I am in the right parent directory and there indeed is a collect directory a level above. Now I'm getting the error: cp: invalid option -- 'o'
What is going wrong?
To handle difficult file names:
find . -name "*.pdf" -type f -exec cp {} ../collect/ \;
By default, find will print the file names that it finds. If one uses the -exec option, it will instead pass the file names on to a command of your choosing, in this case a cp command which is written as:
cp {} ../collect/ \;
The {} tells find where to insert the file name. The end of the command given to -exec is marked by a semicolon. Normally, the shell would eat the semicolon. So, we escape the semicolon with a backslash so that it is passed as an argument to the find command.
Because find gives the file name to cp directly without interference from the shell, this approach works for even the most difficult file names.
More efficiency
The above runs cp on every file found. If there are many files, that would be a lot of processes started. If one has GNU tools, that can be avoided as follows:
find . -name '*.pdf' -type f -exec cp -t ../collect {} +
In this variant of the command, find will supply many file names for each single invocation of cp, potentially greatly reducing the number of processes that need to be started.

Find file without spaces in file name

I'm trying to find all *.cpp, using find files under current directory, which do not contain spaces in neither dirname nor basename. I understand I need to use -wholename flag, but I can not find an appropriate regex syntax.
Use find with a regex:
find . -type f -regex "[^ ]*.cpp"

A question about command "find"

find . \( -name "_*" -or -newer while2 \) -type f -print
In the linux command above , why _* should be quoted ?
First, the shell expands all unquoted *'s to match file names in the local directory.
After that, the shell runs the find command with that list of file names.
Generally, you don't want the shell to do '*' globbing in the local directory. Generally, you wind the find command to do filename matching in other directories.
The shell has several other things it does before running a command. $VARIABLE replacement is one of those.
Why _* should be quoted ?
If it isn't, your shell might expand the * to be substituted with files in the current directory. That's probably not what you wanted here.
if you don't quote it, the shell (bash?) would try to expand. if there's any file that starts with '_' on the current directory, you'd get something like:
find . \(-name _somefile _someother _file3 .... -or -newer while2 \) -type f -print
certainly not what you want. i always quote patterns, just to be sure the shell won't mess with them

Resources