find command in bash shell and the -name option doubts

时光总嘲笑我的痴心妄想 提交于 2020-01-14 18:56:52

问题


What is the difference between the two below:

find . -type f -name \*.bmp
find . -type f -name *.bmp 

I have tested,they both return the same result,so is there anything different _deep inside_?


Added from the removed answer:

So it is to avoid the shell expansion for the special ***** character,solely pass * as a argument to the find command and let it process it.

But on my machine,they are all good, both return the bmp files in and below the current directory,to name a few,the result is like below,some are omitted for brevity

./images/building_color.bmp
./images/building_gray.bmp
./images/car_gray.bmp
./images/temple_color.bmp
./images/boat_gray.bmp
./images/tools_gray.bmp
./images/temple_gray.bmp
./images/tools_color.bmp
./images/car_color.bmp
./images/boat_color.bmp

system info:

GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)

Linux sysabod-laptop 2.6.32-30-generic #59-Ubuntu SMP Tue Mar 1 21:30:21 UTC 2011 i686 GNU/Linux


回答1:


Here's how they're different: the first one always works, and the second one doesn't.

As for why: in bash, shell globs (wildcard patterns including * or ?) are expanded by the shell into all files matching the glob. However, if no such files exist, the pattern is left alone.

So, if you're in a directory with no bmp files, the commands work the same way, because the first is escaped and bash fails to find any files matching in the second case.

If you ran it from a directory containing only one such file, say foo.bmp, the first would find all bmp files in the subtree, while the second would find all files named foo.bmp only. If run in a directory with multiple bmp files, I believe you'll get an error because find doesn't know what to do with all the filenames.




回答2:


When you escape the asterisk (\*) the asterisk itself is passed as argument to the find command and will be evaluated by find. If you don't escape the asterisk (*) already the shell evaluates it and expands it to the file names matching the pattern.

Fore example consider following directory structure:

./a.txt
./b.bmp
./c.bmp
./dir/d.doc
./dir/e.bmp

When you execute

find . -type f -name *.bmp

the shell expands *.bmp to b.bmp c.bmp. I.e. the command that is actually executed will be:

find . -type f -name b.bmp c.bmp

which will find b.bmp and c.bmp but not dir/e.bmp.

When you execute

find . -type f -name \*.bmp

*.bmp is passed directly as it is to find. find will recurse through the current directory (.) and all its subdirectories (in the example only dir) and will find all files in those directories matching the pattern. The result will be: b.bmp, c.bmp and also dir/e.bmp.




回答3:


The first command:

find . -type f -name \*.bmp

passes an asterisk to the find command, and that tells it to find all the files in and below the current directory ending with .bmp.

The second command:

find . -type f -name *.bmp

may be resolved by the shell to, for example:

find . -type f -name image1.bmp image2.bmp image3.bmp

(that would be the bmp files in the current directory only)

and find would only list them, not the bmp files in other directories below the current one.



来源:https://stackoverflow.com/questions/5672577/find-command-in-bash-shell-and-the-name-option-doubts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!