prune - linux find目录




如何在find中排除目录。 命令 (20)

我试图为所有JavaScript文件运行find命令,但是如何排除特定目录?

这是我们使用的查找代码。

for file in $(find . -name '*.js'); do java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file; done

-path -prune方法也适用于路径中的通配符。 下面是一个find语句,它将查找git服务器的目录,该服务器为多个git存储库提供了git内部目录:

find . -type d \
   -not \( -path */objects -prune \) \
   -not \( -path */branches -prune \) \
   -not \( -path */refs -prune \) \
   -not \( -path */logs -prune \) \
   -not \( -path */.git -prune \) \
   -not \( -path */info -prune \) \
   -not \( -path */hooks -prune \)  

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

棘手的部分是, find是非常关注参数的顺序,所以如果你没有把它们恰到好处,你的命令可能无法正常工作。 参数的顺序通常是这样的:

find {path} {options} {action}

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

{options} :在将-name, -iname, etc作为该组的最后一个选项时-name, -iname, etc我获得了最大的成功。 例如-type f -iname '*.js'

{action} :你会想在使用-prune时添加-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

一种选择是使用grep排除包含目录名的所有结果。 例如:

find . -name '*.js' | grep -v excludeddir

以前的答案在Ubuntu上都不是很好。 尝试这个:

find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"

here找到here


例如,如果您想排除misc目录,只需将-path ./misc -prune -o添加到find命令中,请使用prune开关:

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

以下是多个目录的示例:

find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -prune -o -print

在这里,我们排除dir1,dir2和dir3,因为在find表达式中它是一个动作,作用于条件-path dir1 -o -path dir2 -o -path dir3 (如果dir1或dir2或dir3),与typed 。 进一步的行动是-o print ,只是打印。


如果-prune不适合你,这将会:

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

对于FreeBSD用户:

 find . -name '*.js' -not -path '*exclude/this/dir*'

对于工作解决方案(在Ubuntu 12.04(Precise Pangolin)上测试)...

find ! -path "dir1" -iname "*.mp3"

将搜索除dir1子文件夹以外的当前文件夹和子文件夹中的MP3文件。

使用:

find ! -path "dir1" ! -path "dir2" -iname "*.mp3"

...排除dir1和dir2


对于那些不能使用-path-not的旧版UNIX的用户

测试SunOS 5.10 bash 3.2和SunOS 5.11 bash 4.4

find . -type f -name "*" -o -type d -name "*excluded_directory*" -prune -type f

您可以使用修剪选项来实现此目的。 如例如:

find ./ -path ./beta/* -prune -o -iname example.com -print

或者反向grep“grep -v”选项:

find -iname example.com | grep -v beta

您可以在Linux中查找详细的说明和示例find命令排除搜索目录


我发现C源文件中的函数名称排除* .o并排除* .swp和exclude(不是常规文件),并使用此命令排除dir输出:

find .  \( ! -path "./output/*" \) -a \( -type f \) -a \( ! -name '*.o' \) -a \( ! -name '*.swp' \) | xargs grep -n soc_attach

我发现以下比其他建议的解决方案更容易推理:

find build -not \( -path build/external -prune \) -name \*.js

这来自一个实际的用例,我需要在wintersmith生成的一些文件上调用yui-compressor,但是忽略了需要按原样发送的其他文件。

Inside \(\)是一个完全匹配build/external的表达式,并且在成功时避免遍历下面的任何东西 。 然后将它分组为带有转义括号的单个表达式,并以-not为前缀,这将使find跳过与该表达式匹配的任何内容。

有人可能会问,如果添加-not不会使-prune隐藏的所有其他文件重新出现,并且答案是否定的。 -prune工作方式是,任何一旦到达该目录下的文件都会被永久忽略。

这也很容易扩展以增加额外的排除。 例如:

find build -not \( -path build/external -prune \) -not \( -path build/blog -prune \) -name \*.js

我尝试了上面的命令,但没有一个使用“-prune”的人为我工作。 最终我用下面的命令试了一下:

find . \( -name "*" \) -prune -a ! -name "directory"

我想知道目录的数量,文件MB 只是当前目录 - 并且该代码完全是我想要的:-)

来源

- ...    2791037 Jun  2  2011 foo.jpg
- ... 1284734651 Mär 10 16:16 foo.tar.gz
- ...          0 Mär 10 15:28 foo.txt
d ...       4096 Mär  3 17:12 HE
d ...       4096 Mär  3 17:21 KU
d ...       4096 Mär  3 17:17 LE
d ...          0 Mär  3 17:14 NO
d ...          0 Mär  3 17:15 SE
d ...          0 Mär  3 17:13 SP
d ...          0 Mär  3 17:14 TE
d ...          0 Mär  3 19:20 UN

代码

format="%s%'12d\n"

find . -type d -not -path "./*/*" | wc -l | awk -v fmt=$format '{printf fmt, " Anzahl Ordner  = ", $1-1}'
find . -type f -not -path "./*/*" | wc -l | awk -v fmt=$format '{printf fmt, " Anzahl Dateien = ", $1}'
  du . -hmS --max-depth=0 | awk -v fmt=$format '{printf fmt, " Groesse (MB)   = ", $1}'

注意: awk格式化数字需要额外的format="%s%'12d\n"

结果

Anzahl Ordner  =            8
Anzahl Dateien =            3
Groesse (MB)   =        1.228

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

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

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

-o选项表示逻辑或,并分隔命令的两个部分:

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

任何不是 ./misc目录的目录或文件都不会传递第一个测试-path ./misc 。 但是他们会根据第二种表达方式进行测试。 如果他们的名字对应于*.txt模式,那么他们会打印,因为有-print选项。

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


for循环更好地使用exec操作:

find . -path "./dirtoexclude" -prune \
    -o -exec java -jar config/yuicompressor-2.4.2.jar --type js '{}' -o '{}' \;

exec ... '{}' ... '{}' \; 将为每个匹配文件执行一次,用当前文件名替换大括号'{}'

请注意,大括号用单引号括起来,以防止它们被解释为shell脚本标点符号*

笔记

*find (GNU findutils) 4.4.2手册页的EXAMPLES部分


这是唯一为我工作的人。

搜索除“目录”之外的“NameOfFile”。 强调星星*。

find / -name NameOfFile ! -path '*/Directory/*'

这是我用来排除某些路径的格式:

$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"

我用它来查找所有不在“。*”路径中的文件:

$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"

这适用于Mac上的我:

find . -name *.php -or -path "./vendor" -prune -or -path "./app/cache" -prune

它将排除vendorapp/cache目录搜索名称后缀为php


 find . -name '*.js' -\! -name 'glob-for-excluded-dir' -prune




find