想象一下源树。到处都有xml文件。
但由于该树的根部有 XYZ.xml,因此它找不到我的 xml 文件。
find -iname *.xml
回报
./XYZ.xml
代替
./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml
答案1
find -iname '*.xml'
否则,您的 shell 会扩展*.xml
为XYZ.xml
,并且实际执行的命令是
find -iname XYZ.xml
如果当前目录中没有 XML 文件,它会起作用的原因是,如果通配符不匹配任何内容,shell 通常不会展开通配符。一般来说,任何时候您希望通配符由 shell 之外的程序(例如find
、tar
、等)扩展,scp
您需要引用它们,这样 shell 就不会尝试扩展它们本身。
答案2
你需要像这样引用你的论点:
find ./ -name '*.xml'
这样它就会被传递给 find 而不是由 shell 扩展,然后作为扩展版本传递给 find 。
答案3
通配符由 shell 扩展,而不是由命令扩展。find
是少数几个在其自身时间中执行类似于 shell 的通配符匹配的命令之一。
当您运行时ls *.xml
,首先 shell 扩展*.xml
到匹配文件的列表,例如file1.xml
file2.xml
file3.xml
,然后 shellls
使用生成的参数列表进行调用file1.xml
file2.xml
file3.xml
。这就是为什么您会看到与 相同的文件名列表echo *.xml
,即使echo
对文件一无所知并且不关心其参数是否是文件名。
当你跑步时find . -name "*.xml"
:
- shell 解析命令行以识别特殊字符并将其拆分为单词和标点符号。这里只有一个单词列表
find
,.
,-name
,*.xml
其中*
被引用。既然*
被引用,那么就 shell 而言,它是一个普通字符。 - shell
find
使用指定的参数列表运行命令:.
,-name
,*.xml
。 find
*.xml
在当前目录下的任何目录中查找名称与模式匹配的文件。
当您运行find . -name *.xml
并且没有匹配的文件时*.xml
:
- shell 解析命令行以识别特殊字符并将其拆分为单词和标点符号。这里只是一个单词列表
find
,.
,-name
,*.xml
其中*
没有被引用。 - 由于该单词
*.xml
包含不带引号的通配符,因此 shell 会执行文件名生成。由于没有匹配的文件名,因此该模式保持未展开状态。 - shell
find
使用结果参数列表运行该命令,即.
,-name
,*.xml
。 find
*.xml
在当前目录下的任何目录中查找名称与模式匹配的文件。
当您运行find . -name *.xml
并且当前目录包含file1.xml
,file2.xml
和file3.xml
:
- shell 解析命令行以识别特殊字符并将其拆分为单词和标点符号。这里只是一个单词列表
find
,.
,-name
,*.xml
其中*
没有被引用。 - 由于该单词
*.xml
包含不带引号的通配符,因此 shell 执行文件名生成:*.xml
被匹配文件名列表替换。 - shell
find
使用结果参数列表运行命令,即.
,-name
,file1.xml
,file2.xml
,file3.xml
。 find
当到达 时抱怨语法错误file2.xml
。
当您运行find . -name *.xml
并且当前目录包含单个匹配文件时file.xml
:
- shell 解析命令行以识别特殊字符并将其拆分为单词和标点符号。这里只是一个单词列表
find
,.
,-name
,*.xml
其中*
没有被引用。 - 由于该单词
*.xml
包含不带引号的通配符,因此 shell 执行文件名生成:*.xml
被匹配文件名列表替换。 - shell
find
使用结果参数列表运行该命令,即.
,-name
,file.xml
。 find
看到一个完全有效的命令,但它可能不是您想要的:find
被告知查找file.xml
在任何目录中调用的文件,而不是查找任何匹配的文件*.xml
。
(Shell 求值和扩展还有很多其他功能。我只提到了此处相关的功能。)
(我描述的是最常见 shell 的默认行为:sh、bash、dash、ksh 等,某些 shell 可以配置为显示错误,而不是运行带有未扩展通配符的命令,或者将不匹配的通配符扩展为空这些都没有帮助。)
答案4
请尝试:
find ./ -name *.xml