find命令中点和星号的区别

find命令中点和星号的区别

我有一台 Synology NAS,其操作系统使用定制的 Linux。使用该find命令,我尝试列出特定目录中大约 25 天以来修改的文件(排除了一些文件)。

我注意到当我使用“*”而不是“.”时之后find,结果似乎有所不同。请参阅下面的命令:

find . ! -path "*@eaDir*" -type f ! -iname ".DS_Store" ! -iname "Thumbs.db" -mtime -25

find * ! -path "*@eaDir*" -type f ! -iname ".DS_Store" ! -iname "Thumbs.db" -mtime -25

当我使用“.”时,我得到一些相当长一段时间后输出。当我替换“.”时通过“*”,我开始得到更多的结果非常快,并且与使用“.”时不同。

我曾经ls -al检查使用“*”时的结果是否正确,即文件的修改日期/时间是否在最近25天内,确实如此。

谁能告诉我为什么结果不同?

答案1

在:

find * ...

作为 shell 命令行,*是一个 glob,由 shell 扩展到当前目录中的非隐藏条目(按词法排序)列表(对于某些 shell,这只是仅包含有效字符的条目,*如模式表示0个或多个人物)。

因此,如果当前目录包含以下条目:

  • .
  • ..
  • .htaccess
  • file.txt
  • -foo-

find将使用以下参数进行调用:find-foo-file.txt( 和...)。find很可能会抱怨-foo-这是一个无效的选项或谓词。

即使您使用:

find -- * ...

-anything这对于名为or!(...的文件无法正常工作,因为--仅告诉find停止查找选项(例如-L, -H)而不是谓词。

你可以使用:

find ./* ...

以避免出现问题,但话又说回来,这会忽略隐藏文件,可能会忽略具有无效字符的文件或中断(使用arg 列表太长) 如果当前目录中有很多文件。

和:

find . ...

您只需传递.find..是当前目录。然后是find,而不是 shell 会在其中递归地查找文件(包括深度 0 处的文件、除了和 之外.的所有条目(包括其他隐藏条目)、以及子目录的所有其他条目(仍然不包括和)。......

你只想使用:

find ./* ...

如果您希望对深度 1(且仅深度 1)的文件列表进行排序,并希望排除深度 1(且仅深度 1)的隐藏文件。这不太可能。

如果要排除隐藏文件,请添加! -name '.*'Or (尽管要注意包含无效字符的文件名,并且这还将包括恰好与该模式匹配的-name '[!.]*'顶级目录)。find .

如果您想在每个级别进行排序,您可能需要使用zshglob 限定符进行递归通配符。

您得到不同结果的原因很可能是在 中find *, find 首先查找(被告知要查找)当前目录中的第一个文件或目录按字母顺序,并且使用find .,它会查看.自身,然后以不同的顺序查看其中的第一个文件或目录(可能是条目存储在目录中的顺序,但某些find实现还按 inode 编号对列表进行排序,以尽量减少磁盘头寻道)。

顺便说一句,编写命令的更好方法可能是:

find . \( -name @eaDir -o -iname .DS_Store -o -iname Thumbs.db \) \
  -prune -o -mtime -25 -type f -print

这意味着find完全忽略这些目录及其内容(甚至不尝试查看它们的内部)。

答案2

点表示当前目录。通常将其用作find.

朴素的星号将被外壳扩展 find执行到当前目录的内容。这称为“通配”。要查看效果,请执行以下操作:

echo *

毫无疑问,find * ...这不是您想要使用的。

相关内容