更详细的问题是这样的:编写一个shell脚本changeall,它有一个像changeall [ r | -R]string1string2,它将查找所有带.h,.C,.cc或.cpp后缀的文件,并将所有出现的string1更改为string2。注意:1)对于非递归的情况,'ls'是不允许的,我们只能使用'find'和'sed'。2)我尝试了'find -depth'不支持,这就是为什么我想知道'-prune'是否可以帮助,但是不理解'man find'的例子。 $ b $ hr
编辑2:我在做任务,我没有很好的提问,因为我想自己完成,因为我已经完成了,现在我可以说出整个问题。 ,我设法完成了任务,而不使用-prune,但仍然想学习它。
-prune 是一个动作(像 -print ),而不是测试(如 -name )。它改变了待办事项清单,但总是返回true 。 $ b 使用 -prune的一般模式 find [path] [修剪条件] -prune -o \ [你平常的情况] [执行的动作]你几乎总是希望 -o 紧接在 -prune 之后,因为测试的第一部分(最多包括 - prune )将会返回 false 作为你实际需要的东西(即:你不想删除的东西)。
下面是一个例子:
find。 -name.snapshot -prune -o -name'* .foo'-print这会找到不在.snapshot目录下的* .foo文件。在这个例子中, -name .snapshot 是你要修剪的东西的测试, -name'* .foo'-print 是通常放在路径后面的东西。
重要注意事项:
如果您只想打印可能用于省略 -print $ c行动。当使用 -prune 时,通常不要 。 如果除了之外没有任何动作,find的默认行为是使用 -print 动作的整个 (具有讽刺意味的是)在最后。这意味着写这个:
find。 -name.snapshot -prune -o -name'* .foo'#不要这样做相当于写这个:
find。 \(-name .snapshot -prune -o -name'* .foo'\)-print#不要这样做这意味着它也会打印出你正在修剪的目录的名字,这通常不是你想要的。相反,最好是明确地指定 -print 动作,如果这是你想要的:
find。 -name .snapshot -prune -o -name'* .foo'-print#做这个
在输出中包含 .gitignore 。这里是固定版本:
find。 -type d -name'.git *'-prune -o -type f -print#做这个
I don't quite understand the example given from the 'man find', can anyone give me some examples and explanations? Can I combine regular expression in it?
the more detailed question is like this: write a shell script, changeall, which has an interface like "changeall [-r|-R] "string1" "string2". It will find all files with an suffix of .h, .C, .cc, or .cpp and change all occurrences of "string1" to "string2". -r is option for staying in current dir only or including subdir's. NOTE: 1) for non-recursive case, 'ls' is NOT allowed, we could only use 'find' and 'sed'. 2) I tried 'find -depth' but it was NOT supported. That's why I was wondering if '-prune' could help, but didn't understand the example from 'man find'.
EDIT2: I was doing assignment, I didn't ask question in great details because I would like to finish it myself. Since I already done it and hand it in, now I can state the whole question. Also, I managed to finish the assignment without using -prune, but would like to learn it anyway.
解决方案The thing I'd found confusing about about -prune is that it's an action (like -print), not a test (like -name). It alters the "to-do" list, but always returns true.
The general pattern for using -prune is this:
find [path] [conditions to prune] -prune -o \ [your usual conditions] [actions to perform]You pretty much always want the the -o immediately after -prune, because that first part of the test (up to including -prune) will return false for the stuff you actually want (ie: the stuff you don't want to prune out).
Here's an example:
find . -name .snapshot -prune -o -name '*.foo' -printThis will find the "*.foo" files that aren't under ".snapshot" directories. In this example, -name .snapshot is the "tests for stuff you want to prune", and -name '*.foo' -print is the "stuff you'd normally put after the path".
Important notes:
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 THISis equivalent to writing this:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THISwhich 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 THISIf 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 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 THISThis would not include .gitignore in the output. Here's the fixed version:
find . -type d -name '.git*' -prune -o -type f -print # DO THISExtra tip: if you're using the GNU version of find, the texinfo page for find has a more detailed explanation than its manpage (as is true for most GNU utilities).
更多推荐
如何在sh中使用'find'的'
发布评论