我不太理解男士所给出的例子,谁能给我一些例子和解释?我可以在里面结合正则表达式吗?
更详细的问题是这样的:
写一个shell脚本changeall,它有一个类似changeall [-r| -r] "string1" "string2"的接口。它将找到后缀为.h、.c、.cc或.cpp的所有文件,并将所有出现的string1更改为string2。-r是只保留当前目录或包含子目录的选项。
注意:
对于非递归的情况,ls是不允许的,我们只能使用find和sed。
我尝试寻找深度,但它不支持。这就是为什么我想知道-prune是否可以帮助,但不理解从man find的例子。
EDIT2:我在做作业,我没有问太多细节,因为我想自己完成。既然我已经做完并交上来了,现在我可以陈述整个问题了。此外,我没有使用-prune就完成了作业,但无论如何我都想学习它。
修剪是一个“不递归此文件”开关(操作)。
从手册页
如果-depth未指定,则为true;
如果文件是一个目录,不要进入它。
如果给出了-depth,则为false;没有效果。
基本上它不会下降到任何子目录。
举个例子:
您有以下目录:
% find home
home
home/test1
home/test1/test1
home/test2
home/test2/test2
查找home -name test2将打印父目录和名为test2的子目录:
% find home -name test2
home/test2
home/test2/test2
现在,用-西梅…
找到home -name test2 -prune将只打印/home/test2;它不会进入/home/test2找到/home/test2/test2:
% find home -name test2 -prune
home/test2
修剪是一个“不递归此文件”开关(操作)。
从手册页
如果-depth未指定,则为true;
如果文件是一个目录,不要进入它。
如果给出了-depth,则为false;没有效果。
基本上它不会下降到任何子目录。
举个例子:
您有以下目录:
% find home
home
home/test1
home/test1/test1
home/test2
home/test2/test2
查找home -name test2将打印父目录和名为test2的子目录:
% find home -name test2
home/test2
home/test2/test2
现在,用-西梅…
找到home -name test2 -prune将只打印/home/test2;它不会进入/home/test2找到/home/test2/test2:
% find home -name test2 -prune
home/test2
我不是这方面的专家(这个页面和http://mywiki.wooledge.org/UsingFind一起非常有帮助)
注意-path是一个完全匹配find(后面的字符串/path的路径。在这些例子中),其中as -name匹配所有的基名。
find . -path ./.git -prune -o -name file -print
阻塞当前目录中的.git目录(就像你在。目录中找到的一样)
find . -name .git -prune -o -name file -print
递归地阻塞所有.git子目录。
注意。/是非常重要的!!-path必须匹配锚定到的路径。或者在find之后出现的任何东西,如果你匹配了它(从或'-o'的另一边),可能没有被修剪!
我天真地没有意识到这一点,它让我使用-path当它是伟大的,当你不想修剪所有的子目录具有相同的basename:D
添加到其他答案中给出的建议(我没有代表创建回复)…
当将-prune与其他表达式组合使用时,根据所使用的其他表达式,行为会有细微的差异。
@Laurence Gonsalves的例子会找到“*”。Foo“文件不在下面”。快照”目录:-
find . -name .snapshot -prune -o -name '*.foo' -print
然而,这个略有不同的简写也会列出.snapshot目录(以及任何嵌套的.snapshot目录):-
find . -name .snapshot -prune -o -name '*.foo'
根据posix manpage,原因是:
如果给定的表达式不包含任何主-exec,
-ls, -ok,或-print,则给定表达式有效地替换为:
(given_expression) -打印
也就是说,第二个示例相当于输入以下内容,从而修改术语的分组:-
find . \( -name .snapshot -prune -o -name '*.foo' \) -print
至少在Solaris 5.10上可以看到这一点。在使用了大约10年的各种*nix之后,我最近才开始寻找出现这种情况的原因。
我对-prune感到困惑的是,它是一个操作(如-print),而不是一个测试(如name)。它改变了“to-do”列表,但总是返回true。
使用-prune的一般模式如下:
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
你总是想在-prune之后立即使用-o(逻辑或),因为测试的第一部分(直到并包括-prune)对于你真正想要的东西(即:你不想修剪的东西)将返回false。
这里有一个例子:
find . -name .snapshot -prune -o -name '*.foo' -print
这将找到“*”。Foo“文件不在下面”。快照”目录。在本例中,name .snapshot组成[修剪的条件],name '*。Foo ' -print是[您通常的条件]和[要执行的操作]。
重要提示:
If all you want to do is print the results you might be used to leaving out the -print action. You generally don't want to do that when using -prune.
The default behavior of find is to "and" the entire expression with the -print action if there are no actions other than -prune (ironically) at the end. That means that writing this:
find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
is equivalent to writing this:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
which means that it'll also print out the name of the directory you're pruning, which usually isn't what you want. Instead it's better to explicitly specify the -print action if that's what you want:
find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
If your "usual condition" happens to match files that also match your prune condition, those files will not be included in the output. The way to fix this is to add a -type d predicate to your prune condition.
For example, suppose we wanted to prune out any directory that started with .git (this is admittedly somewhat contrived -- normally you only need to remove the thing named exactly .git), but other than that wanted to see all files, including files like .gitignore. You might try this:
find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
This would not include .gitignore in the output. Here's the fixed version:
find . -name '.git*' -type d -prune -o -type f -print # DO THIS
额外提示:如果您使用的是find的GNU版本,那么find的texinfo页面比它的manpage有更详细的解释(大多数GNU实用程序都是如此)。