find命令錯誤提示路徑必須在表達式之前

1、問題

$touch test1.c test2.c text3.txt
$ls
//當前目錄下有三個文件
test1.c  test2.c  text3.txt     

$find . -iname *.txt
./text3.txt

 $find . -iname *.c
$find: paths must precede expression: test2.c
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] 
    [path...] [expression]

 $find . -iname \*.c
./test1.c
./test2.c

$find . -iname "*.c"
./test1.c
./test2.c

2、原因

(1)
man 1 find

 -name pattern
               Base  of  file  name  (the  path  with the leading directories removed) 
               matches shell pattern pattern.  
               The metacharacters (`*', `?', and `[]') match a `.' at the start of the base name 
               (this is a change in findu‐tils-4.2.2; see section STANDARDS CONFORMANCE below).  
               To ignore a directory and the files under it, use -prune; see an example 
               in the description of -path.  
               Braces are not recognised as being special, despite the fact  that  some shells 
               including Bash imbue braces with a special meaning in shell patterns.  
               The filename matching is performed with the use of the fnmatch(3) 
               library function.   
               Don't forget to enclose the pat‐tern in quotes in order to protect it 
               from expansion by the shell.

 -iname pattern
              Like -name, but the match is case insensitive.  For example, 
              the patterns `fo*' and `F??' match the file names `Foo', `FOO', `foo', `fOo', etc.   
              In these patterns, unlike filename will match the file `.foobar'.   
              Please note that you should quote patterns as a matter of course, 
              otherwise the shell will **expand any wildcard characters in them**.

NON-BUGS
       $ find . -name *.c -print
       find: paths must precede expression
       Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] 
       [expression]

       This happens because *.c has been expanded by the shell resulting in find actually 
       receiving a command line like this:

       find . -name bigram.c code.c frcode.c locate.c -print

       That command is of course not going to work.  Instead of doing things this way, 
       you should enclose the pattern in quotes or escape the wildcard:
       $ find . -name \*.c -print

(2)
find -name 選項後面只能支持一個文件的搜索。
“*”是shell的metacharacter(元字符)。
如果直接是 *.txt, 則shell會解析爲test3.txt(當前目錄下只有一個.txt文件), 作爲 pattern,傳遞給find。
變爲: find . -iname test3.txt。故正確。
如果直接是 *.c, 則shell會解析爲test1.c test2.c(當前目錄下有兩個.c文件), 作爲 pattern,傳遞給find。
變爲: find . -iname test1.c test2.c。對test2.c,其前面沒有選項,故報錯。
如果直接是 \*.c 或 “*.c”, 則shell 會把 它當作參數 *.c ,傳給find處理。

參考文獻:
[1] http://blog.csdn.net/firefoxbug/article/details/7618188 作者:firefoxbug
[2] Linux的man手冊 作者:so many people

發佈了30 篇原創文章 · 獲贊 36 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章