文件顶部时查找不递归


8

想象一下一个源代码树。到处都有xml文件。

但是,由于在该树的根目录下有一个XYZ.xml,因此找不到我的xml文件。

find -iname *.xml

退货

./XYZ.xml

代替

./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml

1
来自man find:请注意,您当然应该引用模式,否则shell会在其中扩展任何通配符。
artdanil 2012年

Answers:


18
find -iname '*.xml'

否则,您的外壳将扩展*.xmlXYZ.xml,并且实际执行的命令是

find -iname XYZ.xml

如果当前目录中没有XML文件,那么它起作用的原因是,如果外壳程序不匹配任何内容,它们通常会使通配符不展开。在一般情况下,你想通配符的任何时间比外壳以外的程序扩展(如通过findtarscp,等),你需要说出来了这样的外壳不会尝试扩展它们本身。


1
太简单了,但是几个月来我一直在想如何解决这个问题。我发现这确实很奇怪,而且行为非常不一致,但是现在我明白了,因为它不是找到,而是bash的错。
奥利维尔·图芬

2
这不是bash的“错误”本身,而是您的原因,因为它没有引用您想作为参数传递的通配符。这适用于所有接受shell输入的程序。除非将其引号或转义,否则外壳会将它们扩展为glob。
迦勒(Caleb)

1
我想奥利维尔(Olivier)的意思是,这是的问题bash,而不是的问题find
用户未知,

6

您需要像这样引用您的论点:

find ./ -name '*.xml'

这样它就可以传递给find而不是被shell扩展,然后传递给find作为扩展版本。


1
好的,因此,如果*.xml当前目录中的任何内容都不匹配,则按原样传递它,这就是为什么在其他情况下它仍起作用的原因。很有帮助的答案。
埃里克·威尔逊

1

通配符由外壳而不是命令扩展。find是在自己的时间内执行类似于shell的通配符匹配的少数命令之一。

当您运行时ls *.xml,外壳程序首先扩展*.xml到匹配文件的列表,例如file1.xml file2.xml file3.xml,然后外壳程序ls使用结果的参数列表进行调用file1.xml file2.xml file3.xml。这就是为什么您会看到与相同的文件名列表的原因echo *.xml,即使echo对文件一无所知,也不在乎其参数是否为文件名。

运行时find . -name "*.xml"

  1. Shell解析命令行以识别特殊字符,并将其拆分为单词和标点符号。这里有只是一个单词列表find.-name*.xml其中*被引用。自从*引用起,就外壳而言,它是一个普通字符。
  2. 外壳运行命令find与参数的指定列表:.-name*.xml
  3. find*.xml在当前目录下的任何目录中查找名称与模式匹配的文件。

运行时find . -name *.xml没有匹配的文件*.xml

  1. Shell解析命令行以识别特殊字符,并将其拆分为单词和标点符号。这里有只是一个单词列表find.-name*.xml*没有加引号。
  2. 由于单词*.xml包含未加引号的通配符,因此外壳程序将执行文件名生成。由于没有匹配的文件名,因此模式不会扩展。
  3. 壳运行命令find与所得的参数列表,其是.-name*.xml
  4. find*.xml在当前目录下的任何目录中查找名称与模式匹配的文件。

当您运行find . -name *.xml和当前目录包含file1.xmlfile2.xml以及file3.xml

  1. Shell解析命令行以识别特殊字符,并将其拆分为单词和标点符号。这里有只是一个单词列表find.-name*.xml*没有加引号。
  2. 由于单词*.xml包含未加引号的通配符,因此外壳程序执行文件名生成:*.xml由匹配文件名列表代替。
  3. 壳运行命令find与所得的参数列表,其是.-namefile1.xmlfile2.xmlfile3.xml
  4. find到达时抱怨语法错误file2.xml

当您运行find . -name *.xml并且当前目录包含单个匹配文件时file.xml

  1. Shell解析命令行以识别特殊字符,并将其拆分为单词和标点符号。这里有只是一个单词列表find.-name*.xml*没有加引号。
  2. 由于单词*.xml包含未加引号的通配符,因此外壳程序执行文件名生成:*.xml由匹配文件名列表代替。
  3. 壳运行命令find与所得的参数列表,其是.-namefile.xml
  4. find可以看到一个完全有效的命令,但它可能不是您想要的:find被告知要查找file.xml任何目录中调用的文件,而不要查找任何与匹配的文件*.xml

(Shell评估和扩展还具有许多其他功能。我只在这里提到了相关的功能。)

(我描述的是大多数常见shell的默认行为:sh,bash,dash,ksh等。。。可以将某些shell配置为显示错误,而不是运行带有未扩展通配符的命令,或者将不匹配的通配符扩展为空列表。这些都对这里没有帮助。)


-1

这适用于Solaris 10:

find /directory-to-search/* -prune -name "*gz"


这不会搜索以结尾的名称.xml
库萨兰达

-2

请试试:

find ./ -name *.xml

我刚刚尝试过,同样的结果。
埃里克·威尔逊

我已经尝试过了,而且效果很好。在GNU bash 4.2.8上
bbaja42 2011年

3
当glob与当前目录中的任何内容匹配时,这将不起作用。这是错误的语法!该*应始终引用或转义通过它找到。
Caleb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.