使用find搜索*.js文件时,如何排除特定目录?

find . -name '*.js'

当前回答

我在这个页面上找到了建议,很多其他页面在我的Mac OS X系统上都不起作用。然而,我发现了一种对我有用的变体。

大的想法是搜索Macintosh HD,但避免遍历所有外部卷,这些卷主要是Time Machine备份、映像备份、装载的共享和存档,但不必全部卸载,这通常是不切实际的。

这是我的工作脚本,我将其命名为“findit”。

#!/usr/bin/env bash
# inspired by http://stackoverflow.com/questions/4210042/exclude-directory-from-find-command Danile C. Sobral
# using special syntax to avoid traversing. 
# However, logic is refactored because the Sobral version still traverses 
# everything on my system

echo ============================
echo find - from cwd, omitting external volumes
date
echo Enter sudo password if requested
sudo find . -not \( \
-path ./Volumes/Archive -prune -o \
-path ./Volumes/Boot\ OS\ X -prune -o \
-path ./Volumes/C \
-path ./Volumes/Data -prune -o \
-path ./Volumes/jas -prune -o \
-path ./Volumes/Recovery\ HD -prune -o \
-path ./Volumes/Time\ Machine\ Backups -prune -o \
-path ./Volumes/SuperDuper\ Image -prune -o \
-path ./Volumes/userland -prune \
\) -name "$1" -print
date
echo ============================
iMac2:~ jas$

不同的路径与外部存档卷、Time Machine、虚拟机、其他装载的服务器等有关。一些卷名中有空格。

一个好的测试运行是“finditindex.php”,因为该文件出现在我的系统中的许多地方。使用此脚本,搜索主硬盘大约需要10分钟。如果没有这些例外,这需要很多小时。

其他回答

有很多好的答案,我只是花了一些时间来理解命令的每个元素是什么以及背后的逻辑。

find . -path ./misc -prune -o -name '*.txt' -print

find将开始查找当前目录中的文件和目录,因此查找。。

-o选项代表逻辑OR,并将命令的两部分分开:

[ -path ./misc -prune ] OR [ -name '*.txt' -print ]

不是的任何目录或文件/misc目录不会通过第一个测试路径/其他。但他们将根据第二个表达式进行测试。如果它们的名称与模式*.txt相对应,则会因为-print选项而被打印。

当find到达时/misc目录,此目录仅满足第一个表达式。因此,将对其应用-prune选项。它告诉find命令不要浏览该目录。中的任何文件或目录/find甚至不会探索misc,不会针对表达式的第二部分进行测试,也不会打印。

不确定这是否能涵盖所有边缘情况,但以下内容将非常简单明了:

ls-1 | grep-v-e ddl-e docs | xargs rm-rf

这将从当前目录excpet“ddls”和“docs”中删除所有文件/目录。

-prune绝对有效,并且是最好的答案,因为它可以防止下降到要排除的目录中-not-path仍然搜索排除的目录,它只是不打印结果,如果排除的目录已装入网络卷或您没有权限,这可能是一个问题。

棘手的是,find对参数的顺序非常讲究,所以如果你不能正确地获取它们,你的命令可能无法正常工作。论点的顺序一般如下:

find {path} {options} {action}

{path}:首先放置所有与路径相关的参数,如-路径'/dir1'-修剪-o

{options}:将-name、-iname等作为此组中的最后一个选项时,我最成功。例如-type f-iname“*.js”

{action}:使用-prine时需要添加-print

下面是一个工作示例:

# setup test
mkdir dir1 dir2 dir3
touch dir1/file.txt; touch dir1/file.js
touch dir2/file.txt; touch dir2/file.js
touch dir3/file.txt; touch dir3/file.js

# search for *.js, exclude dir1
find . -path './dir1' -prune -o -type f -iname '*.js' -print

# search for *.js, exclude dir1 and dir2
find . \( -path './dir1' -o -path './dir2' \) -prune -o -type f -iname '*.js' -print

如果-prune对你不起作用,这将:

find -name "*.js" -not -path "./directory/*"

注意:需要遍历所有不需要的目录。

我更喜欢-不是符号。。。它更可读:

find . -name '*.js' -and -not -path directory