我有一台 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
.
如果您想在每个级别进行排序,您可能需要使用zsh
glob 限定符进行递归通配符。
您得到不同结果的原因很可能是在 中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 * ...
这不是您想要使用的。