我不太理解男士所给出的例子,谁能给我一些例子和解释?我可以在里面结合正则表达式吗?
更详细的问题是这样的:
写一个shell脚本changeall,它有一个类似changeall [-r| -r] "string1" "string2"的接口。它将找到后缀为.h、.c、.cc或.cpp的所有文件,并将所有出现的string1更改为string2。-r是只保留当前目录或包含子目录的选项。
注意:
对于非递归的情况,ls是不允许的,我们只能使用find和sed。
我尝试寻找深度,但它不支持。这就是为什么我想知道-prune是否可以帮助,但不理解从man find的例子。
EDIT2:我在做作业,我没有问太多细节,因为我想自己完成。既然我已经做完并交上来了,现在我可以陈述整个问题了。此外,我没有使用-prune就完成了作业,但无论如何我都想学习它。
添加到其他答案中给出的建议(我没有代表创建回复)…
当将-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之后,我最近才开始寻找出现这种情况的原因。
通常,我们在Linux中做事的原生方式,以及我们思考的方式,是从左到右的。
你可以先写下你想要的东西:
find / -name "*.php"
然后,您按下ENTER键,并意识到您从不想获取的目录中获取了太多文件。
因此,您认为“让我们排除/media以避免搜索挂载驱动器。”
现在你只需要将以下内容添加到前面的命令中:
-print -o -path '/media' -prune
最后一个命令是:
find / -name "*.php" -print -o -path '/media' -prune
|<-- Include -->|<-- Exclude -->|
我认为这种结构要简单得多,而且与正确的方法相关。
添加到其他答案中给出的建议(我没有代表创建回复)…
当将-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之后,我最近才开始寻找出现这种情况的原因。
如果你读了这里所有的好答案,我现在的理解是,以下都返回相同的结果:
find . -path ./dir1\* -prune -o -print
find . -path ./dir1 -prune -o -print
find . -path ./dir1\* -o -print
#look no prune at all!
但最后一个将花费更长的时间,因为它仍然搜索dir1中的所有内容。我想真正的问题是如何在不实际搜索的情况下删除不需要的结果。
所以我猜prune的意思是不要美化过去的比赛,而是把它标记为已经完成…
http://www.gnu.org/software/findutils/manual/html_mono/find.html
“然而,这并不是由于‘修剪’动作的影响(它只是防止进一步下降,并不能确保我们忽略该项目)。相反,这种效果是由于使用了' -o '。由于./src/emacs的" or "条件左边已经成功,因此对于这个特定的文件,根本没有必要计算右边(' -print ')的值。"
我对-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实用程序都是如此)。