Why does find . -name foo* fail? - linux

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.

Related

How do I find a file containing using wildcard on 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'

Linux find catalogs and print only names

i wanna search for the catalogs which have the "program" in their names and echo these names in console. I have wrote this, but isn't working:
find usr -type d -name "program" -exec echo {}
The error is find: missing argument to `-exec'.
find usr -type d -name "program"
usr/lib64/libreofice/program
How to fix my command?
Some tiny example with the * wildcard.
find /my/path -name "*program*"
If you don' use wildcards, it will try to find exactly the files named program. Also, echoing is done automatically, you don't need the exec command.
Update
Answering to your comment. You can get the base name (name without the path) with:
find . -name "*program*" -exec basename {} \;

find command with regex to find directories

I have the following linux find command that gives a base path then also searches if there are any directories that contain the name 3.7.1
In my base path /some/folder/path/folder1 i would like to change folder1 into a regular expression something like folder[1-3] how can I do this?
# working command
find /some/folder/path/folder1/another_folder -type d -name "3.7.1*" -ls
# would like to use some regular expresion on folder1-3
find /some/folder/path/folder[1-3]/another_folder -type d -name "3.7.1*" -ls
error I am seeing: /folder[1-3]/another_folder/': No such file or directory
That's the correct syntax already:
find /some/folder/path/folder[1-3] -type d -name "3.7.1*" -ls

How to use variable as a path for find command

Can someone give me a hint, how I can make the following bash script run properly:
path="/path/"
excludepath="! -path \"/path/to/exclude/*\" "
find "$path" "$excludepath" -name *."txt" -type f
When I try to run it I get:
find: `! -path "/path/to/exclude/*"': No such file or directory
Thank you in advance.
Your problem was the fact that "$excludepath" is a single argument, even if it contains spaces. To put several arguments, use an array of strings instead of a string:
excludepath=(! -path "*webshow*")
find "$path" "${excludepath[#]}" -name "*.txt" -type f
This is a bashism, though (people that stumble onto this and don't use bash will need to do something else).

wild cards on find and ls

I'm trying to figure out the wild-cards to do file operations.
I have these files in a directory for testing purposes:
file_BSD.GIF file_linux.gif file_unix
See my ls command,
$ ls *{.GIF,.gif}
file_BSD.GIF file_linux.gif
Which is OK.
But "find" doesn't seem to work the same way:
$ find -name *{.GIF,.gif}
find: paths must precede expression: file_linux.gif
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
By the way, I've read that "-iname" should locate both the uppercase and lowercase files, but that doesn't seem to work either:
$find -iname *.gif
./file_linux.gif
(This should locate the .GIF file as well, right?).
find -name *{.GIF,.gif} is wrong.
This command is first expanded by the shell to find -name *.GIF *.gif
Then further expanded to :
find -name file_BSD.GIF file_linux.gif
# as you have only these files in directory
Now this -name file_BSD.GIF file_linux.gif is passed to find. And this is wrong as there is no switch like file_linux.gif that is accepted by find.
What you need is this command.
find -name '*.GIF' -or -name '*.gif'
Assuming you want to collect .gif files in a case insensitive manner, this find command becomes,
find -iname '*.gif'
Note the single quotes (') here. It means *.GIF should be sent to find as is without any shell expansion. And find will use this as pattern. This single quote is necessary unless you escape the shell meta-characters. In that case the command would look like
find -iname \*.gif
You are having trouble with the parameter -iname of find because you must quote the patterns you give to it.
So, you should do:
find -iname '*.gif'
This is stated in the manual:
"... Please note that you should quote patterns as a matter of course, otherwise the shell will expand any wildcard characters in them."
You should understand that (in contrast to Windows) the shell is expanding the *{.GIF,.gif} before passing it to the find program.
You can feel what the shell does by replacing the program with echo.
So you should quote the program argument, like
echo \-name '*{.GIF,.gif}'
so run
find -name '*.{GIF,gif}'
Maybe you want
find -name '*.gif' -o -name '*.GIF'
Please read the Advanced Bash Scripting Guide (and perhaps the execve(2) man page, to understand how the kernel run programs).

Resources