如何在sh中使用'find'的'

编程入门 行业动态 更新时间:2024-10-20 09:28:28
本文介绍了如何在sh中使用'find'的'-prune'选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我不太明白男人找的例子,谁能给我一些例子和解释?我可以结合正则表达式吗?

更详细的问题是这样的:编写一个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 如果除了之外没有任何动作,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#做这个

  • <如果你的平常条件恰好匹配了与你的修剪条件相匹配的文件,那么这些文件就不会被包含在输出中。解决这个问题的方法是在修剪条件中添加一个 -type d 谓词。

    例如,假设我们希望删除以 .git 开头的任何目录(这是无可厚非的 - 通常你只需要正确删除名为的东西 code> .git ),但除此之外,希望查看所有文件,包括像 .gitignore 这样的文件。你可以试试这个:

    find。 -name'.git *'-prune -o -type f -print#不要这样做

    在输出中包含 .gitignore 。这里是固定版本:

    find。 -type d -name'.git *'-prune -o -type f -print#做这个

  • 特别提示:如果您使用 find 的GNU版本,那么的texinfo页面找到比它的manpage有更详细的解释(对于大多数GNU工具来说都是如此)。

    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' -print

    This 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 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 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 . -type d -name '.git*' -prune -o -type f -print # DO THIS

  • Extra 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'的'

    本文发布于:2023-11-23 19:53:17,感谢您对本站的认可!
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:如何在   sh   find

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!