bash:如何从find命令中过滤出目录和扩展名?

4
我正在尝试使用以下方法查找最近修改的文件。
find . -mtime 0

这使我

en/content/file.xml
es/file.php
en/file.php.swp
css/main.css
js/main.js

但我想过滤掉enes目录,但想抓取其他所有内容。此外,我希望从这些结果中过滤掉.swp文件。

所以我想得到:

css/main.css
js/main.js
xml/foo.xml

除了位于 es/en 文件夹以外且不以 .swp 结尾的所有其他文件。
5个回答

13

在 find 中正确使用:

find -mtime 0 -not \( -name '*.swp' -o -path './es*' -o -path './en*' \)

好的回答!find 命令很棒,但在不同的 UNIX 版本中实现有所不同,因此我更喜欢易于记忆且使用更多带有标准选项的命令的解决方案。 - mmonem
我可以同意这一点,但是从提问者的标签和声望来看,我认为他应该知道 grep 并不是一个选项。将其限制在 find 中允许更多灵活的输出/操作(如 -exec-ls-print0-printf,...)。 - mvds
(顺便说一句,“bash”标签意味着GNU) - mvds
-exec、-ls和-print是非常著名的命令,我个人在AIX中使用它们时几乎没有区别。我的观点是:很难记住find命令的“有点”复杂的匹配和修改选项,而存在其他简单易记的选项。 - mmonem

3

试试这个:

find . -mtime 0 | grep -v '^en' | grep -v '^es'

在给grep提供的模式开头添加cap字符可以确保必须在行首找到该模式。 更新:根据Chen Levy的评论,使用以下内容替代上述内容。
find . -mtime 0 | grep -v '^\./en' | grep -v '^\./es'

虽然find命令很强大,但在不同的UNIX版本中实现方式有所不同,因此我更喜欢易于记忆并且使用标准选项更多的解决方案。


锚定模式确实使其更加健壮。我已更新我的答案以匹配它。 - speshak
请查看我对@speshak答案的评论。同时,可以在不使用grep的情况下完成此工作。 - Chen Levy
你已经接近成功了。请注意,在正则表达式中,.是有意义的,尝试使用\.代替它,然后你可以回到最初的答案,使用^\./es匹配行首。 - Chen Levy

3
-prune 命令可以防止 find 命令进入你想要避免的目录:
find . \( -name en -o -name es \) -prune , -mtime 0 ! -name "*.swp"

2
find . -mtime 0 | grep -v '^en' | grep -v '^es' | grep -v .swp

grep 的 -v 标志会返回所有不匹配模式的行。

这可能不起作用:find . 的输出将返回以 ./ 开头的行,因此 grep -v "^e..." 将无法匹配,因此也无法过滤掉不想要的行。 - Chen Levy

0

find(1) 的 -regex 选项(可以与 -E 选项结合使用以启用扩展正则表达式)也匹配整个文件路径。

find . -mtime 0 -not \( -name '*.swp' -o -regex '\./es.*' -o -regex '\./en.*' \)
find "$(pwd -P)" -mtime 0 -not \( -name '*.swp' -o -regex '.*/es.*' -o -regex '.*/en.*' \)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接