find command in bash shell and the -name option do

2019-07-03 19:43发布

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

3条回答
\"骚年 ilove
2楼-- · 2019-07-03 20:20

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楼-- · 2019-07-03 20:22

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.

查看更多
唯我独甜
4楼-- · 2019-07-03 20:29

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.

查看更多
登录 后发表回答