我有一个文件隐藏在某处,它的名字是file.foo.bar.txt
或file.bar.foo.txt
,但我不确定它是哪一个。
现在,我正在运行,find file*foo*txt
因为我知道文件会在列表中,但我必须对列表进行排序才能找到实际的文件。
主要是出于好奇(列表很短而且实际上我可以找到该文件),有没有办法find file.(foo&bar).txt
可以找到该文件,而不管哪个是实际文件?
答案1
该命令find file*foo*txt
实际上并没有使用find
。
你的 shell在运行file*foo*txt
之前find
就已经扩展了。然后find
获取可能很多的参数作为它的起点;没有测试,没有操作。默认操作-print
是假定的。
这就像printf '%s\n' file*foo*txt
。printf
和find
都只打印 shell 提供的内容;除非没有匹配项。或者除非 shell 返回目录名称(可能还有其他名称);在这种情况下printf
只会打印它,而find
会打印它以及每个目录的路径文件在目录中,递归地。
您的任务可以通过find
(而不是 shell)实际执行一些匹配来完成。使用多个-name
测试。默认行为是使用(逻辑 AND)连接测试-a
。这适合于您希望文件名同时匹配多个模式的情况。
find . -type f -name 'file.*' -name '*.txt' -name '*.foo.*' -name '*.bar.*'
笔记:
- 这些模式不是正则表达式。
*
这里是通配符,但是.
是文字。我使用是.
因为你写了“file.foo.bar.txt
或file.bar.foo.txt
”。 find
是递归的。使用-maxdepth 1
或者(如果你find
不支持)阅读以下内容:将 POSIX 限制find
到特定深度。- 注意,这些模式被引号括起来。这是为了防止它们被 shell 扩展(比较这个问题)。
如果您想要从字面上file.foo.bar.txt
或file.bar.foo.txt
然后使用-o
(逻辑或):
find . -type f \( -name file.foo.bar.txt -o -name file.bar.foo.txt \)
笔记你经常需要用括号-o
。没有他们我们-type f -name … -o -name …
就无法实现我们的愿望。
还有-regex
。这是整个路径上的匹配和有几种口味。
答案2
中的默认操作find
是和,因此对于松散的匹配,你可以使用
find . -name 'file*foo*txt' -name 'file*bar*txt'
但对于严格匹配,您可以采用正则表达式:
find . -regextype posix-extended -regex '.*/file\.(foo\.bar|bar\.foo)\.txt'
您需要记住正则表达式必须匹配完整路径,因此.*/
在开头。