我有一台 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
Run Code Online (Sandbox Code Playgroud)
当我使用“.”时,很长一段时间后我得到了一些输出。当我替换“.”时 通过“*”,我开始很快获得更多结果,并且它们与使用“.”时不同。
我曾经ls -al检查使用“*”时的结果是否正确,即文件的修改日期/时间是否在最近25天内,确实如此。
谁能告诉我为什么结果不同?
在:
find * ...
Run Code Online (Sandbox Code Playgroud)
作为 shell 命令行,*是一个 glob,由 shell 扩展到当前目录中的非隐藏条目(按词法排序)列表(对于某些 shell,这只是仅包含有效字符的条目,*如模式表示 0 个或多个字符)。
因此,如果当前目录包含以下条目:
....htaccessfile.txt-foo-find将使用以下参数进行调用:find、-foo-、file.txt( 和...)。find很可能会抱怨这-foo-是一个无效的选项或谓词。
即使您使用:
find -- * ...
Run Code Online (Sandbox Code Playgroud)
-anything这对于名为or!或(...的文件无法正常工作,因为--仅告诉find停止查找选项(例如-L, -H)而不是谓词。
你可以使用:
find ./* ...
Run Code Online (Sandbox Code Playgroud)
为了避免这些问题,但话又说回来,如果当前目录中有很多文件,这将省略隐藏文件,可能会省略具有无效字符的文件或中断( arg list 太长)。
和:
find . ...
Run Code Online (Sandbox Code Playgroud)
您只需传递.到find. .是当前目录。然后是find,而不是 shell 会在其中递归地查找文件(包括.深度 0 处的文件、除 和 之外的所有条目(.包括..其他隐藏条目)以及深度 1 处的子目录的所有其他条目(仍然不包括.和..)。
你只想使用:
find ./* ...
Run Code Online (Sandbox Code Playgroud)
如果您希望对深度 1(且仅深度 1)的文件列表进行排序,并希望排除深度 1(且仅深度 1)的隐藏文件。这不太可能。
如果要排除隐藏文件,请添加! -name '.*'Or (尽管要注意包含无效字符的文件名,并且这还将包括恰好与该模式匹配的-name '[!.]*'顶级目录)。find .
如果您想在每个级别进行排序,您可能需要zsh使用 glob 限定符进行递归通配符。
您得到不同结果的原因很可能是在 中, find 首先按字母find *顺序查找(被告知要查找)当前目录中的第一个文件或目录,而使用 时,它会查找自身,然后查找下一个以不同的顺序排列其中的第一个文件或目录(可能是条目存储在目录中的顺序,但某些实现还按 inode 编号对列表进行排序,以尽量减少磁盘头寻道)。find ..find
顺便说一句,编写命令的更好方法可能是:
find . \( -name @eaDir -o -iname .DS_Store -o -iname Thumbs.db \) \
-prune -o -mtime -25 -type f -print
Run Code Online (Sandbox Code Playgroud)
这意味着find完全忽略这些目录及其内容(甚至不尝试查看它们的内部)。
点表示当前目录。通常将其用作find.
在执行到当前目录的内容之前, shell 将扩展朴素的星号。find这称为“通配”。要查看效果,请执行以下操作:
echo *
Run Code Online (Sandbox Code Playgroud)
毫无疑问,find * ...这不是您想要使用的。