我目前正在构建一个脚本来处理目录中的一些文件。在第一个示例中,我使用 find 命令并传递一个目录作为参数。在第二个中,我使用 find 命令上的 -name 开关来传递所需的文件名。但是有人可以向我解释下面两者之间的区别吗?因为它们产生完全相同的输出:
find dump* -type f -mtime +5 | xargs ls -ltrh
find $dir -type f -name "dump*" -mtime +5 | xargs ls -ltrh
请假设在上面的示例中,它正在包含文件的目录中运行。然而,在第二种情况下,它可以从任何地方运行。我主要关心的是文件路径与名称部分;因此,如果可以的话,请集中注意力。
如果之前有人问过这个问题,我们深表歉意。我试着寻找,但找不到任何东西。
谢谢。
答案1
在第一种情况下,dump*
由 shell 解释,并扩展为匹配的文件名,然后传递给find
.实际上,find
看到:
find dumpa dumpb ... -type f ...
在第二种情况下,shell 不进行任何解释。find
进行过滤。因此,考虑到 的递归性质find
,第二种方法可以找到第一种方法会错过的文件。
第二种方法更灵活,因为您可以使用变量来形成-name
/-path
过滤器,但是很难获得shell 扩展通配符在一个变量中。根据您的用例,其中一个都是正确的,但在所有情况下都可以更正第二个以匹配第一个(使用其他find
选项,例如maxdepth
、 或prune
),但反之则不然。
考虑:
$ tree .
.
├── dumpa
│ └── dumpc
├── dumpb
├── dumpd
└── not-dump
└── dumpe
$ find . -type f -name 'dump*'
./not-dump/dumpe
./dumpd
./dumpa/dumpc
$ find dump* -type f
dumpa/dumpc
dumpd
另请注意,如果没有任何内容与通配符匹配,则第一个将导致错误,但第二个将成功但没有任何结果:
$ find blahblah* -type f
find: `blahblah*': No such file or directory
$ find . -name 'blahblah*' -type f
$
我更喜欢第二种方法,因为:
- 它更灵活。
- 不易出错。在没有匹配项的情况下使用通配符可能会引起麻烦。如果可以的话,我会避免通配符的外壳扩展,特别是如果我
find
手头有这样的工具。
还有一个不相关的点,跳过xargs
:
find ... -exec ls -lrth {} +