如何使用“查找”在SH“-prune”选项?(How to use '-prune'

2019-07-19 22:57发布

我不太明白从“找人”,任何人都可以给我一些例子和说明中给出的例子吗? 我可以在它结合正则表达式?


更详细的问题是这样的:写一个shell脚本,changeall,其中有像“changeall [-r | -R]‘的界面字符串1’,‘字符串2’将会找到.H,.C的后缀的所有文件。 ,.cc的,或者的.cpp和更改“字符串1”到“字符串2” -r选项是为住在只有当前目录或子目录包含的注意所有出现:1)对非递归的情况下,“LS”是不允许的,我们只能用“发现”和“sed的” 2)我想“发现-depth”,但它是不支持的。这就是为什么我在想,如果“-prune”能帮上忙,但不理解“的例子男人找”。


EDIT2:我是做任务,我并没有很详细的问问题,因为我想自己完成它。 既然我已经做了它,并把它的,现在我可以说出整个问题。 另外,我设法完成,而无需使用-prune分配,但想反正去学习它。

Answer 1:

我已经找到混淆约约的事情-prune是它的一个动作(如-print ),不是测试(如-name )。 它改变了“待办事项”列表, 但总是返回true。

使用一般模式-prune是这样的:

find [path] [conditions to prune] -prune -o \
            [your usual conditions] [actions to perform]

你几乎总是希望-o (逻辑OR)后立即-prune ,因为测试的是第一部分(直至并包括-prune )会为你真正想要的东西(即返回false:不这样做的东西要修剪出)。

下面是一个例子:

find . -name .snapshot -prune -o -name '*.foo' -print

这将找到“* .foo”此时的文件是不是在“.snapshot”目录。 在这个例子中, -name .snapshot拼成[conditions to prune] ,和-name '*.foo' -print[your usual conditions][actions to perform]

重要提示

  1. 如果你想要做的就是打印结果,你可能被用来留下了-print动作。 通常,您不想使用时,要做到这一点-prune

    发现的默认行为是“和”与整个表达式-print动作,如果有比其它任何操作-prune末(讽刺)。 这意味着,写这个:

     find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS 

    相当于写这个:

     find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS 

    这意味着它还会打印出你修剪的目录中,这通常是不是你想要的名称。 相反,它是最好明确指定-print动作,如果这就是你想要什么:

     find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS 
  2. 如果你的“通常条件”恰好匹配也符合您修剪条件文件,这些文件将不会被包含在输出中。 解决这个问题的办法是增加一个-type d谓词到你的修剪条件。

    例如,假设我们想修剪,随着启动的任何目录.git (这是无可否认有些做作-通常你只需要删除名为完全相同的事情.git ),但除此之外,想看到所有文件,包括文件喜欢.gitignore 。 你可以试试这个:

     find . -name '.git*' -prune -o -type f -print # DON'T DO THIS 

    包括.gitignore输出。 下面是固定的版本:

     find . -type d -name '.git*' -prune -o -type f -print # DO THIS 

额外提示:如果您使用的GNU版本find ,对于文本信息文件find具有比其手册页更详细的解释(这是大多数的GNU工具真)。



Answer 2:

要注意的是-prune并不妨碍下降到任何目录中有些人所说。 它可以防止降入匹配它应用到测试目录。 也许有些例子可以帮助(见正则表达式例如底部)。 对不起,这是如此漫长。

$ find . -printf "%y %p\n"    # print the file type the first time FYI
d .
f ./test
d ./dir1
d ./dir1/test
f ./dir1/test/file
f ./dir1/test/test
d ./dir1/scripts
f ./dir1/scripts/myscript.pl
f ./dir1/scripts/myscript.sh
f ./dir1/scripts/myscript.py
d ./dir2
d ./dir2/test
f ./dir2/test/file
f ./dir2/test/myscript.pl
f ./dir2/test/myscript.sh

$ find . -name test
./test
./dir1/test
./dir1/test/test
./dir2/test

$ find . -prune
.

$ find . -name test -prune
./test
./dir1/test
./dir2/test

$ find . -name test -prune -o -print
.
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

$ find . -regex ".*/my.*p.$"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test/myscript.pl

$ find . -name test -prune -regex ".*/my.*p.$"
(no results)

$ find . -name test -prune -o -regex ".*/my.*p.$"
./test
./dir1/test
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test

$ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py

$ find . -not -regex ".*test.*"                   .
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2


Answer 3:

通常情况下,原生方式,我们做的事情在Linux和我们的思维方式是由左到右。
所以,你会去写你在找什么第一:

find / -name "*.php"

那么你可能按下回车键,并意识到你是从目录中得到太多的文件您不希望。 让我们排除/媒体以避免搜索你安装的驱动器。
您现在应该只是追加以下到以前的命令:

-print -o -path '/media' -prune

因此最终的命令是:

find / -name "*.php" -print -o -path '/media' -prune

............... | <---包括---> | .................... | < - -------- ---------排除> |

我认为,这种结构更容易和关联到正确的方法



Answer 4:

添加到在其他的答案提出的意见(我没有代表创建回复)...

当组合-prune与其他表达式,存在行为取决于被用于其上其它表达式一个微妙的差异。

@Laurence贡萨尔维斯例子会发现,是不是在“.snapshot”目录‘* .foo’此时文件: -

find . -name .snapshot -prune -o -name '*.foo' -print

然而,这稍微不同的短手会,也许不经意间,也列出了.snapshot目录(以及任何嵌套.snapshot目录): -

find . -name .snapshot -prune -o -name '*.foo'

究其原因是(根据我的系统上的联机帮助页): -

如果给定的表达不包含任何初选的-exec,-ls,-OK,或-print,给定的表达被有效地替换为:

(given_expression)-print

也就是说,第二个例子是进入下文中,从而修改的术语的分组相当于: -

find . \( -name .snapshot -prune -o -name '*.foo' \) -print

这至少已经看到了在Solaris上5.10。 有* nix中所使用的各种口味的大约10年里,我是最近才搜索的原因会出现这种情况。



Answer 5:

西梅是没有在任何目录开关递归。

从该名男子页

如果-depth没有给出,真实的; 如果该文件是目录,不要落在其中。 如果-depth给定,虚假的; 没有效果。

基本上,它不会desend到任何子目录。

就拿这个例子:

您有以下目录

  • /家/ TEST2
  • /家庭/ TEST2 / TEST2

如果您运行find -name test2

它将返回两个目录

如果您运行find -name test2 -prune

它只会返回/主页/ test2的,因为它不会沦落成/家庭/ test2将查找/主页/ TEST2 / TEST2



Answer 6:

我在这方面的专家(与该页面一起非常有帮助http://mywiki.wooledge.org/UsingFind )

只注意到-path是, 充分,只是之后而来的字符串/路径匹配的路径find.在论文的实例),其中作为-name所有基本名称相匹配。

find . -path ./.git  -prune -o -name file  -print

块在当前目录中的.git目录如您的发现.

find . -name .git  -prune -o -name file  -print

阻止所有git的子目录递归。

注意./是非常重要的! -path必须挂靠在一个路径匹配. 或是有如果你得到了它的比赛(从的另一侧或“ 刚过找到 -o ”)有可能不被修剪! 我天真地意识到这一点,并把我使用-path时,它是伟大的,当你不想修剪与相同基的所有子目录:d



Answer 7:

显示一切,包括目录本身而不是它的冗长的内容:

find . -print -name dir -prune


Answer 8:

如果你看过所有的好答案在这里我的理解现在是以下所有返回相同的结果:

find . -path ./dir1\*  -prune -o -print

find . -path ./dir1  -prune -o -print

find . -path ./dir1\*  -o -print
#look no prune at all!

但是,最后一个将需要更长的时间,因为它仍然检索出Dir1中的一切。 我想真正的问题是如何-or掉不想要的结果,而实际上他们搜索。

所以我想修剪方式做不正经过去的比赛,但将其标记为已完成...

http://www.gnu.org/software/findutils/manual/html_mono/find.html “这个然而,这不是由于‘-prune’行动的效果(只防止进一步的血统,它并不保证我们忽略了项目)。取而代之的是,这种效果是由于使用“-o”。由于左侧的“或”条件已成功为./src/emacs,没有必要评价右手端都为这个特定的文件(“-print”)“。



文章来源: How to use '-prune' option of 'find' in sh?